// Refresh repository metadata once every 2 hours
#define REFRESH_AGE_METADATA 2 * 3600
+#define MAX_DESCRIPTION 4096
+#define MAX_KEY 4096
+
struct pakfire_repo_appdata {
- char* description;
- char* baseurl;
+ // Description
+ char description[MAX_DESCRIPTION];
+
+ // Base URL
+ char baseurl[PATH_MAX];
// Refresh Interval
time_t refresh;
// Key
- char* key;
+ char key[MAX_KEY];
// Mirrorlist
- char* mirrorlist_url;
+ char mirrorlist_url[PATH_MAX];
char mirrorlist[PATH_MAX];
// Markers
if (pakfire_repo_is_commandline(repo))
return 1;
- if (!repo->appdata->baseurl)
- return 0;
-
return pakfire_string_startswith(repo->appdata->baseurl, "file://");
}
return strcmp(n, name) == 0;
}
+char* pakfire_repo_url_replace(struct pakfire_repo* repo, const char* url) {
+ if (!url)
+ return NULL;
+
+ const struct replacement {
+ const char* pattern;
+ const char* replacement;
+ } replacements[] = {
+ { "%{name}", pakfire_repo_get_name(repo) },
+ { "%{arch}", pakfire_get_effective_arch(repo->pakfire) },
+ { "%{distro}", pakfire_get_distro_id(repo->pakfire) },
+ { "%{version}", pakfire_get_distro_version_id(repo->pakfire) },
+ { NULL },
+ };
+
+ char* buffer = strdup(url);
+ if (!buffer)
+ return NULL;
+
+ for (const struct replacement* repl = replacements; repl->pattern; repl++) {
+ // Skip if there is no replacement
+ if (!repl->replacement)
+ continue;
+
+ char* r = pakfire_string_replace(
+ buffer, repl->pattern, repl->replacement);
+ free(buffer);
+
+ // Break on any errors
+ if (!r)
+ return NULL;
+
+ // Free the old buffer and continue working with the new data
+ buffer = r;
+ }
+
+#ifdef ENABLE_DEBUG
+ if (strcmp(url, buffer) != 0) {
+ DEBUG(repo->pakfire, "Repository URL updated:");
+ DEBUG(repo->pakfire, " From: %s\n", url);
+ DEBUG(repo->pakfire, " To : %s\n", buffer);
+ }
+#endif
+
+ return buffer;
+}
+
#define pakfire_repo_path(repo, path, format, ...) \
__pakfire_repo_path(repo, path, sizeof(path), format, __VA_ARGS__)
const unsigned char* expected_digest,
const size_t expected_digest_length,
enum pakfire_transfer_flags flags) {
- struct pakfire_downloader* downloader;
- int r = pakfire_downloader_create(&downloader, repo->pakfire);
+ struct pakfire_downloader* downloader = NULL;
+ char* baseurl = NULL;
+ int r;
+
+ // Create downloader
+ r = pakfire_downloader_create(&downloader, repo->pakfire);
if (r)
- return r;
+ goto ERROR;
+
+ // Prepare the baseurl
+ baseurl = pakfire_repo_url_replace(repo, repo->appdata->baseurl);
+ if (!baseurl) {
+ r = -errno;
+ goto ERROR;
+ }
#if 0
// Fetch mirrorlist
#endif
// Retrieve the database file
- r = pakfire_downloader_retrieve(downloader, repo->appdata->baseurl, NULL,
+ r = pakfire_downloader_retrieve(downloader, baseurl, NULL,
title, url, path, md, expected_digest, expected_digest_length, flags);
#if 0
if (mirrorlist)
pakfire_mirrorlist_unref(mirrorlist);
#endif
- pakfire_downloader_unref(downloader);
+
+ERROR:
+ if (downloader)
+ pakfire_downloader_unref(downloader);
+ if (baseurl)
+ free(baseurl);
return r;
}
static int pakfire_repo_import_key(struct pakfire_repo* repo, const char* data) {
- struct pakfire_key* key = NULL;
int r;
// Free any formerly imported keys (this should not happen)
}
// If the key could be successfully imported, we will store it in the appdata
- repo->appdata->key = strdup(data);
- if (!repo->appdata->key) {
+ r = pakfire_string_set(repo->appdata->key, data);
+ if (r) {
ERROR(repo->pakfire, "Could not copy the key to appdata: %m\n");
- r = 1;
goto ERROR;
}
ERROR:
- if (key)
- pakfire_key_unref(key);
-
return r;
}
}
static int pakfire_repo_refresh_mirrorlist(struct pakfire_repo* repo, const int force) {
+ char* url = NULL;
int r;
// Local repositories don't need a mirrorlist
return 0;
// This repository does not have a mirrorlist
- if (!repo->appdata->mirrorlist_url)
+ if (!*repo->appdata->mirrorlist_url)
return 0;
// Make path to mirrorlist
r = pakfire_cache_path(repo->pakfire, repo->appdata->mirrorlist,
"repodata/%s/mirrorlist", pakfire_repo_get_name(repo));
if (r)
- return r;
+ goto ERROR;
// Check if this needs to be refreshed
if (!force) {
}
}
- return pakfire_repo_retrieve(repo, NULL,
- repo->appdata->mirrorlist_url, repo->appdata->mirrorlist,
+ // Replace any variables in the URL
+ url = pakfire_repo_url_replace(repo, repo->appdata->mirrorlist_url);
+ if (!url) {
+ ERROR(repo->pakfire, "Could not expend the mirror list URL: %m\n");
+ r = -errno;
+ goto ERROR;
+ }
+
+ r = pakfire_repo_retrieve(repo, NULL, url, repo->appdata->mirrorlist,
0, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS);
+
+ERROR:
+ if (url)
+ free(url);
+
+ return r;
}
static int pakfire_repo_download_metadata(struct pakfire_repo* repo, const char* path, int force) {
}
static void free_repo_appdata(struct pakfire_repo_appdata* appdata) {
- if (!appdata)
- return;
-
- if (appdata->key)
- free(appdata->key);
-
- if (appdata->description)
- free(appdata->description);
-
- if (appdata->mirrorlist_url)
- free(appdata->mirrorlist_url);
-
- free(appdata);
+ if (appdata)
+ free(appdata);
}
static void pakfire_repo_free(struct pakfire_repo* repo, const int free_repo) {
}
PAKFIRE_EXPORT int pakfire_repo_set_description(struct pakfire_repo* repo, const char* description) {
- if (repo->appdata->description)
- free(repo->appdata->description);
-
- if (description)
- repo->appdata->description = strdup(description);
- else
- repo->appdata->description = NULL;
-
- return 0;
+ return pakfire_string_set(repo->appdata->description, description);
}
PAKFIRE_EXPORT int pakfire_repo_get_enabled(struct pakfire_repo* repo) {
return repo->appdata->baseurl;
}
-static char* pakfire_repo_url_replace(struct pakfire_repo* repo, const char* url) {
- if (!url)
- return NULL;
-
- const struct replacement {
- const char* pattern;
- const char* replacement;
- } replacements[] = {
- { "%{name}", pakfire_repo_get_name(repo) },
- { "%{arch}", pakfire_get_effective_arch(repo->pakfire) },
- { "%{distro}", pakfire_get_distro_id(repo->pakfire) },
- { "%{version}", pakfire_get_distro_version_id(repo->pakfire) },
- { NULL },
- };
-
- char* buffer = strdup(url);
- if (!buffer)
- return NULL;
-
- for (const struct replacement* repl = replacements; repl->pattern; repl++) {
- // Skip if there is no replacement
- if (!repl->replacement)
- continue;
-
- char* r = pakfire_string_replace(
- buffer, repl->pattern, repl->replacement);
- free(buffer);
-
- // Break on any errors
- if (!r)
- return NULL;
-
- // Free the old buffer and continue working with the new data
- buffer = r;
- }
-
-#ifdef ENABLE_DEBUG
- if (strcmp(url, buffer) != 0) {
- DEBUG(repo->pakfire, "Repository URL updated:");
- DEBUG(repo->pakfire, " From: %s\n", url);
- DEBUG(repo->pakfire, " To : %s\n", buffer);
- }
-#endif
-
- return buffer;
-}
-
PAKFIRE_EXPORT int pakfire_repo_set_baseurl(struct pakfire_repo* repo, const char* baseurl) {
- if (repo->appdata->baseurl)
- free(repo->appdata->baseurl);
+ int r;
- // Store URL
- repo->appdata->baseurl = pakfire_repo_url_replace(repo, baseurl);
- if (!repo->appdata->baseurl)
- return 1;
+ // Store the URL
+ r = pakfire_string_set(repo->appdata->baseurl, baseurl);
+ if (r)
+ return r;
// Update sub-priority
pakfire_repo_update_subpriority(repo);
PAKFIRE_EXPORT struct pakfire_key* pakfire_repo_get_key(struct pakfire_repo* repo) {
int r;
- if (!repo->key && repo->appdata->key) {
+ // It looks like no key has been imported
+ if (!*repo->appdata->key)
+ return NULL;
+
+ // Import the key
+ if (!repo->key) {
r = pakfire_key_import_from_string(&repo->key, repo->pakfire,
repo->appdata->key, strlen(repo->appdata->key));
if (r)
- goto ERROR;
+ return NULL;
}
- if (repo->key)
- return pakfire_key_ref(repo->key);
-
-ERROR:
- return NULL;
+ return pakfire_key_ref(repo->key);
}
PAKFIRE_EXPORT const char* pakfire_repo_get_mirrorlist_url(struct pakfire_repo* repo) {
}
PAKFIRE_EXPORT int pakfire_repo_set_mirrorlist_url(struct pakfire_repo* repo, const char* url) {
- if (repo->appdata->mirrorlist_url)
- free(repo->appdata->mirrorlist_url);
-
- // Store URL
- repo->appdata->mirrorlist_url = pakfire_repo_url_replace(repo, url);
- if (!repo->appdata->mirrorlist_url)
- return 1;
-
- return 0;
+ return pakfire_string_set(repo->appdata->mirrorlist_url, url);
}
PAKFIRE_EXPORT int pakfire_repo_write_config(struct pakfire_repo* repo, FILE* f) {
// Prefix path with file:// to form baseurl
r = pakfire_string_format(baseurl, "file://%s", realpath);
if (r)
- return 1;
+ goto ERROR;
// Create a new temporary repository at path
r = pakfire_repo_create(&repo, pakfire, "tmp");
if (r) {
ERROR(pakfire, "Could not create a temporary repository: %m\n");
- return r;
+ goto ERROR;
}
// Set baseurl to path
r = 0;
ERROR:
- pakfire_repo_clear(repo);
- pakfire_repo_unref(repo);
+ if (repo) {
+ pakfire_repo_clear(repo);
+ pakfire_repo_unref(repo);
+ }
return r;
}