#define MAX_PARALLEL 4
struct pakfire_transfer {
- struct pakfire* pakfire;
+ struct pakfire_ctx* ctx;
int nrefs;
// Reference to the downloader
};
struct pakfire_downloader {
- struct pakfire* pakfire;
+ struct pakfire_ctx* ctx;
int nrefs;
unsigned int parallel;
// Initialize cURL
r = curl_global_init(CURL_GLOBAL_DEFAULT);
if (r) {
- ERROR(downloader->pakfire, "Could not initialize cURL: %d\n", r);
+ CTX_ERROR(downloader->ctx, "Could not initialize cURL: %d\n", r);
return r;
}
// Create a new multi handle
downloader->curl = curl_multi_init();
if (!downloader->curl) {
- ERROR(downloader->pakfire, "Could not create cURL multi handle\n");
+ CTX_ERROR(downloader->ctx, "Could not create cURL multi handle\n");
return 1;
}
pakfire_mirrorlist_unref(transfer->mirrors);
if (transfer->progress)
pakfire_progress_unref(transfer->progress);
- if (transfer->pakfire)
- pakfire_unref(transfer->pakfire);
+ if (transfer->ctx)
+ pakfire_ctx_unref(transfer->ctx);
free(transfer);
}
if (downloader->curl)
curl_multi_cleanup(downloader->curl);
-
- pakfire_unref(downloader->pakfire);
+ if (downloader->ctx)
+ pakfire_ctx_unref(downloader->ctx);
free(downloader);
}
-int pakfire_downloader_create(struct pakfire_downloader** downloader, struct pakfire* pakfire) {
+int pakfire_downloader_create(
+ struct pakfire_downloader** downloader, struct pakfire_ctx* ctx) {
struct pakfire_downloader* d = NULL;
int r;
+#warning The OFFLINE flag must be moved into the context
+#if 0
// Fail if pakfire is running in offline mode
if (pakfire_has_flag(pakfire, PAKFIRE_FLAGS_OFFLINE)) {
ERROR(pakfire, "Cannot initialize downloader in offline mode\n");
return -ENOTSUP;
}
+#endif
// Allocate a new object
d = calloc(1, sizeof(*d));
if (!d)
return -ENOMEM;
- // Store reference to Pakfire
- d->pakfire = pakfire_ref(pakfire);
+ // Store reference to the context
+ d->ctx = pakfire_ctx_ref(ctx);
// Initialize reference counting
d->nrefs = 1;
#ifdef ENABLE_DEBUG
static int debug_callback(CURL *handle, curl_infotype type,
char* data, size_t size, void* private) {
- struct pakfire* pakfire = (struct pakfire*)private;
+ struct pakfire_ctx* ctx = private;
switch (type) {
case CURLINFO_TEXT:
- DEBUG(pakfire, "cURL: %.*s", (int)size, data);
+ CTX_DEBUG(ctx, "cURL: %.*s", (int)size, data);
break;
// Log headers
case CURLINFO_HEADER_IN:
- DEBUG(pakfire, "cURL: < %.*s", (int)size, data);
+ CTX_DEBUG(ctx, "cURL: < %.*s", (int)size, data);
break;
case CURLINFO_HEADER_OUT:
- DEBUG(pakfire, "cURL: > %.*s", (int)size, data);
+ CTX_DEBUG(ctx, "cURL: > %.*s", (int)size, data);
break;
// Ignore everything else
static size_t pakfire_downloader_transfer_write(
char* data, size_t size, size_t nmemb, void* p) {
struct pakfire_transfer* transfer = p;
+ struct pakfire_ctx* ctx = transfer->ctx;
int r;
// Do not write empty blocks
if (transfer->evp) {
r = EVP_DigestUpdate(transfer->evp, data, nmemb);
if (r != 1) {
- ERROR(transfer->downloader->pakfire, "EVP_DigestUpdate failed: %s\n",
+ CTX_ERROR(ctx, "EVP_DigestUpdate failed: %s\n",
ERR_error_string(ERR_get_error(), NULL));
return 0;
}
int r;
// Fetch global configuration
- config = pakfire_get_config(downloader->pakfire);
+ config = pakfire_ctx_get_config(downloader->ctx);
// Set global configuration
if (config) {
curl_easy_setopt(transfer->handle, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(transfer->handle, CURLOPT_DEBUGFUNCTION, debug_callback);
- curl_easy_setopt(transfer->handle, CURLOPT_DEBUGDATA, downloader->pakfire);
+ curl_easy_setopt(transfer->handle, CURLOPT_DEBUGDATA, downloader->ctx);
#endif
// Limit protocols to HTTPS, HTTP, FTP and FILE
if (!t)
return -errno;
- // Store a reference to Pakfire
- t->pakfire = pakfire_ref(downloader->pakfire);
+ // Store a reference to the context
+ t->ctx = pakfire_ctx_ref(downloader->ctx);
// Initialize the reference counter
t->nrefs = 1;
// No mirror found
if (!transfer->mirror) {
- ERROR(downloader->pakfire, "No mirrors left to try\n");
+ CTX_ERROR(downloader->ctx, "No mirrors left to try\n");
// No mirrors left
return ENOENT;
}
- DEBUG(downloader->pakfire, "Selected mirror %s\n", pakfire_mirror_get_url(transfer->mirror));
+ CTX_DEBUG(downloader->ctx, "Selected mirror %s\n", pakfire_mirror_get_url(transfer->mirror));
return 0;
}
if (!*transfer->path)
return 0;
- DEBUG(downloader->pakfire,
+ CTX_DEBUG(downloader->ctx,
"Download successful. Storing result in %s\n", transfer->path);
// Flush any buffered data out to disk
// Move the temporary file to its destination
r = link(transfer->tempfile, transfer->path);
if (r) {
- ERROR(downloader->pakfire, "Could not link destination file %s: %m\n",
+ CTX_ERROR(downloader->ctx, "Could not link destination file %s: %m\n",
transfer->path);
return r;
}
if (times.modtime) {
r = utime(transfer->path, ×);
if (r)
- ERROR(downloader->pakfire, "Could not set mtime of %s: %m\n", transfer->path);
+ CTX_ERROR(downloader->ctx, "Could not set mtime of %s: %m\n", transfer->path);
}
return 0;
struct pakfire_transfer* transfer, int code) {
int r;
- DEBUG(downloader->pakfire, "Transfer failed\n");
+ CTX_DEBUG(downloader->ctx, "Transfer failed\n");
// Get file descriptor
int fd = fileno(transfer->f);
if (r)
return r;
- DEBUG(downloader->pakfire, "cURL transfer done: %d - %s\n",
+ CTX_DEBUG(downloader->ctx, "cURL transfer done: %d - %s\n",
code, curl_easy_strerror(code));
// Finish message digest computation
if (transfer->evp) {
r = EVP_DigestFinal_ex(transfer->evp, transfer->computed_digest, &transfer->computed_digest_length);
if (r != 1) {
- ERROR(downloader->pakfire, "Could not finish message digest computation: %s\n",
+ CTX_ERROR(downloader->ctx, "Could not finish message digest computation: %s\n",
ERR_error_string(ERR_get_error(), NULL));
return 1;
}
// Effective URL
curl_easy_getinfo(h, CURLINFO_EFFECTIVE_URL, &url);
if (url)
- DEBUG(downloader->pakfire, " Effective URL: %s\n", url);
+ CTX_DEBUG(downloader->ctx, " Effective URL: %s\n", url);
// Response code
curl_easy_getinfo(h, CURLINFO_RESPONSE_CODE, &response_code);
if (response_code)
- DEBUG(downloader->pakfire, " Response code: %ld\n", response_code);
+ CTX_DEBUG(downloader->ctx, " Response code: %ld\n", response_code);
// HTTP Version
curl_easy_getinfo(h, CURLINFO_HTTP_VERSION, &http_version);
if (http_version)
- DEBUG(downloader->pakfire, " HTTP Version: %s\n", curl_http_version(http_version));
+ CTX_DEBUG(downloader->ctx, " HTTP Version: %s\n", curl_http_version(http_version));
// Total Times
curl_easy_getinfo(h, CURLINFO_TOTAL_TIME, &total_time);
- DEBUG(downloader->pakfire, " Total Time: %.2fs\n", total_time);
+ CTX_DEBUG(downloader->ctx, " Total Time: %.2fs\n", total_time);
// Download Size
curl_easy_getinfo(h, CURLINFO_SIZE_DOWNLOAD_T, &download_size);
if (download_size)
- DEBUG(downloader->pakfire, " Download Size: %ld bytes\n", download_size);
+ CTX_DEBUG(downloader->ctx, " Download Size: %ld bytes\n", download_size);
// Download Speed
curl_easy_getinfo(h, CURLINFO_SPEED_DOWNLOAD_T, &speed);
if (speed)
- DEBUG(downloader->pakfire, " Download Speed: %ld bps\n", speed);
+ CTX_DEBUG(downloader->ctx, " Download Speed: %ld bps\n", speed);
// Message Digest
char* hexdigest = __pakfire_hexlify(transfer->computed_digest, transfer->computed_digest_length);
if (hexdigest) {
- DEBUG(downloader->pakfire, " Message Digest: %s\n", hexdigest);
+ CTX_DEBUG(downloader->ctx, " Message Digest: %s\n", hexdigest);
free(hexdigest);
}
char* expected_hexdigest = __pakfire_hexlify(transfer->expected_digest,
transfer->expected_digest_length);
- ERROR(downloader->pakfire, "Download checksum for %s didn't match:\n", transfer->url);
- ERROR(downloader->pakfire, " Expected: %s\n", expected_hexdigest);
- ERROR(downloader->pakfire, " Computed: %s\n", computed_hexdigest);
+ CTX_ERROR(downloader->ctx, "Download checksum for %s didn't match:\n", transfer->url);
+ CTX_ERROR(downloader->ctx, " Expected: %s\n", expected_hexdigest);
+ CTX_ERROR(downloader->ctx, " Computed: %s\n", computed_hexdigest);
if (computed_hexdigest)
free(computed_hexdigest);
progress_flags |= PAKFIRE_PROGRESS_NO_PROGRESS;
// Make a new progress meter
- r = pakfire_progress_create(&transfer->progress, transfer->pakfire, progress_flags, parent);
+ r = pakfire_progress_create(&transfer->progress, transfer->ctx, progress_flags, parent);
if (r)
return r;
// Fail if we could not set the URL
} else {
- ERROR(downloader->pakfire, "Invalid transfer %s\n", transfer->url);
+ CTX_ERROR(downloader->ctx, "Invalid transfer %s\n", transfer->url);
return -EINVAL;
}
if (!transfer->f) {
r = pakfire_downloader_transfer_prepare_tmpfile(transfer);
if (r) {
- ERROR_ERRNO(transfer->pakfire, r, "Could not open a temporary file: %m\n");
+ CTX_ERROR(downloader->ctx, "Could not open a temporary file: %s\n", strerror(-r));
return r;
}
}
if (transfer->md) {
transfer->evp = EVP_MD_CTX_new();
if (!transfer->evp) {
- ERROR(downloader->pakfire, "Could not create EVP context: %m\n");
+ CTX_ERROR(downloader->ctx, "Could not create EVP context: %m\n");
return 1;
}
// Initialize the EVP context
r = EVP_DigestInit_ex(transfer->evp, transfer->md, NULL);
if (r != 1) {
- ERROR(downloader->pakfire, "Could not initialize EVP context: %s\n",
+ CTX_ERROR(downloader->ctx, "Could not initialize EVP context: %s\n",
ERR_error_string(ERR_get_error(), NULL));
return 1;
}
struct pakfire_transfer* transfer, struct pakfire_progress* progress) {
int r;
- DEBUG(downloader->pakfire, "Starting transfer %p...\n", transfer);
+ CTX_DEBUG(downloader->ctx, "Starting transfer %p...\n", transfer);
// Prepare the transfer
r = pakfire_downloader_transfer_prepare(downloader, transfer, progress, 0);
// Add the handle to cURL
r = curl_multi_add_handle(downloader->curl, transfer->handle);
if (r) {
- ERROR(downloader->pakfire, "Adding handle failed: %s\n", curl_multi_strerror(r));
+ CTX_ERROR(downloader->ctx, "Adding handle failed: %s\n", curl_multi_strerror(r));
return r;
}
const unsigned int num_queued_transfers = pakfire_downloader_total_queued_transfers(downloader);
// Create a new progress indicator
- r = pakfire_progress_create(&progress, downloader->pakfire, progress_flags, NULL);
+ r = pakfire_progress_create(&progress, downloader->ctx, progress_flags, NULL);
if (r)
goto ERROR;
// Run cURL
r = curl_multi_perform(downloader->curl, &still_running);
if (r) {
- ERROR(downloader->pakfire, "cURL error: %s\n", curl_easy_strerror(r));
+ CTX_ERROR(downloader->ctx, "cURL error: %s\n", curl_easy_strerror(r));
goto ERROR;
}
break;
default:
- ERROR(downloader->pakfire, "Received unhandled cURL message %u\n", msg->msg);
+ CTX_ERROR(downloader->ctx, "Received unhandled cURL message %u\n", msg->msg);
break;
}
}