char* description;
char* baseurl;
- char metadata[PATH_MAX];
-
// Key fingerprint
char key[PAKFIRE_KEY_FPR_MAXLEN];
return pakfire_repo_name_equals(repo, PAKFIRE_REPO_COMMANDLINE);
}
+#define pakfire_repo_path(repo, path, format, ...) \
+ __pakfire_repo_path(repo, path, sizeof(path), format, __VA_ARGS__)
+
+static int __pakfire_repo_path(struct pakfire_repo* repo,
+ char* path, const size_t length, const char* format, ...) {
+ char buffer[PATH_MAX];
+ va_list args;
+ int r;
+
+ // Format the path
+ va_start(args, format);
+ r = __pakfire_string_vformat(buffer, sizeof(buffer), format, args);
+ va_end(args);
+ if (r)
+ return r;
+
+ // For local repositories return the local path
+ if (pakfire_repo_is_local(repo))
+ return __pakfire_string_format(path, length,
+ "%s/%s", pakfire_repo_get_path(repo), buffer);
+
+ const char* name = pakfire_repo_get_name(repo);
+
+ // Otherwise return the cached path
+ return __pakfire_cache_path(repo->pakfire, path, length, "%s/%s", name, buffer);
+}
+
static int pakfire_repo_retrieve(
struct pakfire_repo* repo,
const char* title,
return pakfire_mirrorlist_ref(repo->mirrorlist);
}
-static int pakfire_repo_download_database(struct pakfire_repo* repo, const char* database,
- const char* cache_path) {
+static int pakfire_repo_download_database(struct pakfire_repo* repo,
+ const char* filename, const char* path) {
char title[NAME_MAX];
- char database_url[PATH_MAX];
+ char url[PATH_MAX];
+ int r;
// Do nothing if the file already exists
- if (pakfire_path_exists(cache_path)) {
- DEBUG(repo->pakfire, "Database %s already present. Skipping download\n", database);
+ if (pakfire_path_exists(path)) {
+ DEBUG(repo->pakfire, "Database %s already present. Skipping download\n", filename);
return 0;
}
const char* name = pakfire_repo_get_name(repo);
// Make title
- pakfire_string_format(title, _("Package Database: %s"), name);
+ r = pakfire_string_format(title, _("Package Database: %s"), name);
+ if (r)
+ return r;
// Make download URL
- pakfire_string_format(database_url, "repodata/%s", database);
+ r = pakfire_string_format(url, "repodata/%s", filename);
+ if (r)
+ return r;
- return pakfire_repo_retrieve(repo, title, database_url, cache_path,
- 0, NULL, 0, 0);
+ return pakfire_repo_retrieve(repo, title, url, path, 0, NULL, 0, 0);
}
-static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* path, int refresh) {
+static int pakfire_repo_read_database(struct pakfire_repo* repo, const char* path) {
FILE* f = NULL;
int r;
+ DEBUG(repo->pakfire, "Read package database from %s...\n", path);
+
+ // Open the database file
+ f = fopen(path, "r");
+ if (!f) {
+ ERROR(repo->pakfire, "Could not open package database at %s: %m\n", path);
+ r = 1;
+ goto ERROR;
+ }
+
+ // Drop any previous data
+ r = pakfire_repo_clear(repo);
+ if (r)
+ goto ERROR;
+
+ // Read database
+ r = pakfire_repo_read_solv(repo, f, 0);
+ if (r)
+ goto ERROR;
+
+ERROR:
+ if (f)
+ fclose(f);
+
+ return r;
+}
+
+static int pakfire_repo_read_metadata(struct pakfire_repo* repo, const char* path) {
+ char database_path[PATH_MAX];
+ int r;
+
+ DEBUG(repo->pakfire, "Reading repository metadata from %s...\n", path);
+
struct json_object* json = pakfire_json_parse_from_file(repo->pakfire, path);
if (!json) {
- // Ignore metadata not existing when not on refresh mode
- if (!refresh && errno == ENOENT)
- return 0;
+ switch (errno) {
+ case ENOENT:
+ // If the repository is local, we will just scan it
+ if (pakfire_repo_is_local(repo)) {
+ DEBUG(repo->pakfire, "No metadata available on local repository."
+ " Falling back to scan...\n");
+
+ return pakfire_repo_scan(repo, 0);
+ }
+ break;
+ }
ERROR(repo->pakfire, "Could not parse metadata from %s: %m\n", path);
return 1;
}
- char database_filename[NAME_MAX] = "";
- char database_cache_path[PATH_MAX];
-
struct json_object* database = NULL;
// Search for the database name
int found = json_object_object_get_ex(json, "database", &database);
- if (found) {
- pakfire_string_set(database_filename, json_object_get_string(database));
-
- DEBUG(repo->pakfire, "Using package database %s\n", database_filename);
+ if (!found) {
+ ERROR(repo->pakfire, "Could not read database name from metadata\n");
+ r = 1;
+ goto ERROR;
}
- // Try loading the database
- if (*database_filename) {
- r = pakfire_cache_path(repo->pakfire, database_cache_path,
- "repodata/%s/%s", pakfire_repo_get_name(repo), database_filename);
- if (r)
- goto ERROR;
+ const char* filename = json_object_get_string(database);
- // Download the database if necessary
- if (refresh) {
- r = pakfire_repo_download_database(repo, database_filename, database_cache_path);
- if (r)
- goto ERROR;
- }
+ // Make the path to the database
+ r = pakfire_repo_path(repo, database_path, "repodata/%s", filename);
+ if (r)
+ goto ERROR;
- // Drop any previous data
- r = pakfire_repo_clear(repo);
+ // Download the database
+ if (!pakfire_repo_is_local(repo) && !pakfire_has_flag(repo->pakfire, PAKFIRE_FLAGS_OFFLINE)) {
+ r = pakfire_repo_download_database(repo, filename, database_path);
if (r)
goto ERROR;
-
- // Open database file
- f = fopen(database_cache_path, "r");
- if (!f)
- goto ERROR;
-
- // Read database
- r = pakfire_repo_read_solv(repo, f, 0);
- if (r) {
- if (!refresh && errno == ENOENT)
- goto NOERROR;
-
- ERROR(repo->pakfire, "Could not read SOLV file %s: %m\n", database_cache_path);
- goto ERROR;
- }
}
-NOERROR:
- // Success
- r = 0;
+ // Read the database
+ r = pakfire_repo_read_database(repo, database_path);
+ if (r)
+ goto ERROR;
ERROR:
- if (f)
- fclose(f);
-
// Free the parsed JSON object
json_object_put(json);
}
static int pakfire_repo_refresh_mirrorlist(struct pakfire_repo* repo, const int force) {
+ int r;
+
+ // Local repositories don't need a mirrorlist
+ if (pakfire_repo_is_local(repo))
+ return 0;
+
+ // Do nothing if running in offline mode
+ if (pakfire_has_flag(repo->pakfire, PAKFIRE_FLAGS_OFFLINE))
+ return 0;
+
// This repository does not have a mirrorlist
- if (!repo->appdata->mirrorlist_url || !*repo->appdata->mirrorlist)
+ 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;
+
// Check if this needs to be refreshed
if (!force) {
time_t age = pakfire_path_age(repo->appdata->mirrorlist);
0, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS);
}
-static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int force) {
+static int pakfire_repo_download_metadata(struct pakfire_repo* repo, const char* path, const int force) {
// Check if this needs to be refreshed
if (!force) {
- time_t age = pakfire_path_age(repo->appdata->metadata);
+ time_t age = pakfire_path_age(path);
if (age > 0 && age < REFRESH_AGE_METADATA) {
DEBUG(repo->pakfire, "Skip refreshing metadata which is %lds old\n", age);
}
}
- int r = pakfire_repo_retrieve(repo, NULL,
- "repodata/repomd.json", repo->appdata->metadata, 0,
- NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS);
+ return pakfire_repo_retrieve(repo, NULL, "repodata/repomd.json", path,
+ 0, NULL, 0, PAKFIRE_TRANSFER_NOPROGRESS);
+}
+
+static int pakfire_repo_refresh_metadata(struct pakfire_repo* repo, const int force) {
+ char path[PATH_MAX];
+ int r;
+
+ // Make the metadata path
+ r = pakfire_repo_path(repo, path, "%s", "repodata/repomd.json");
if (r)
return r;
- // Parse metadata
- r = pakfire_repo_read_metadata(repo, repo->appdata->metadata, 1);
- if (r) {
- unlink(repo->appdata->metadata);
- return r;
+ // Don't try to refresh the metadata for local repositories and if we are running offline
+ if (!pakfire_repo_is_local(repo) && !pakfire_has_flag(repo->pakfire, PAKFIRE_FLAGS_OFFLINE)) {
+ r = pakfire_repo_download_metadata(repo, path, force);
+ if (r)
+ return r;
}
- return 0;
+ // Parse metadata
+ return pakfire_repo_read_metadata(repo, path);
}
static void free_repo_appdata(struct pakfire_repo_appdata* appdata) {
if (r)
goto ERROR;
- // Skip remaining initialization for "internal" repositories
- if (pakfire_repo_is_internal(rep))
- goto SUCCESS;
-
- // Make path to mirrorlist
- r = pakfire_cache_path(pakfire, rep->appdata->mirrorlist,
- "repodata/%s/mirrorlist", pakfire_repo_get_name(rep));
- if (r)
- goto ERROR;
-
- // Make path for metadata
- r = pakfire_cache_path(pakfire, rep->appdata->metadata,
- "repodata/%s/repomd.json", pakfire_repo_get_name(rep));
- if (r)
- goto ERROR;
-
- // Try loading metadata
- r = pakfire_repo_read_metadata(rep, rep->appdata->metadata, 0);
- if (r) {
- ERROR(rep->pakfire, "Could not initialize repository metadata: %m\n");
- goto ERROR;
- }
-
SUCCESS:
*repo = rep;
return 0;
return 0;
}
- // Scan local repositories
- if (pakfire_repo_is_local(repo))
- return pakfire_repo_scan(repo, 0);
-
- // Do nothing if running in offline mode
- if (pakfire_has_flag(repo->pakfire, PAKFIRE_FLAGS_OFFLINE))
- return 0;
-
// Refresh mirrorlist
r = pakfire_repo_refresh_mirrorlist(repo, force);
if (r) {