// POST MIME Object
curl_mime* mime;
+ // Transfer direction
+ enum {
+ PAKFIRE_TRANSFER_DOWNLOAD = 0,
+ PAKFIRE_TRANSFER_UPLOAD = 1,
+ } direction;
+
// Size
size_t expected_size;
size_t transferred;
}
#endif
+static size_t pakfire_downloader_transfer_read(char* data, size_t size, size_t nmemb, void* p) {
+ struct pakfire_transfer* transfer = p;
+
+ return fread(data, size, nmemb, transfer->f);
+}
+
+static int pakfire_downloader_transfer_seek(void* p, curl_off_t offset, int origin) {
+ struct pakfire_transfer* transfer = p;
+ int r;
+
+ // Perform the seek
+ r = fseek(transfer->f, (long)offset, origin);
+ if (r < 0)
+ return CURL_SEEKFUNC_CANTSEEK;
+
+ return CURL_SEEKFUNC_OK;
+}
+
static size_t pakfire_downloader_transfer_write(
char* data, size_t size, size_t nmemb, void* p) {
struct pakfire_transfer* transfer = p;
// Follow any redirects
curl_easy_setopt(transfer->handle, CURLOPT_FOLLOWLOCATION, 1);
+ // Read any data from a callback function
+ curl_easy_setopt(transfer->handle,
+ CURLOPT_READFUNCTION, pakfire_downloader_transfer_read);
+ curl_easy_setopt(transfer->handle, CURLOPT_READDATA, transfer);
+
// Write all data to the callback function
curl_easy_setopt(transfer->handle,
CURLOPT_WRITEFUNCTION, pakfire_downloader_transfer_write);
curl_easy_setopt(transfer->handle, CURLOPT_WRITEDATA, transfer);
+ // Register the seek callback
+ curl_easy_setopt(transfer->handle,
+ CURLOPT_SEEKFUNCTION, pakfire_downloader_transfer_seek);
+ curl_easy_setopt(transfer->handle, CURLOPT_SEEKDATA, transfer);
+
// Success
r = 0;
return 0;
}
+int pakfire_downloader_transfer_set_input(struct pakfire_transfer* transfer, FILE* f) {
+ struct stat stat;
+ int r;
+
+ // Fetch the file descriptor
+ const int fd = fileno(f);
+
+ // Change direction
+ transfer->direction = PAKFIRE_TRANSFER_UPLOAD;
+
+ // Store the file handle
+ transfer->f = f;
+
+ // Try to find the upload size
+ if (fd > 0) {
+ r = fstat(fd, &stat);
+ if (r)
+ return 0;
+
+ // Store the expected filesize
+ transfer->expected_size = stat.st_size;
+ }
+
+ return 0;
+}
+
int pakfire_downloader_transfer_set_target(
struct pakfire_transfer* transfer, const char* path) {
return pakfire_string_set(transfer->path, path);
}
}
+ // Set special options for direction
+ switch (transfer->direction) {
+ case PAKFIRE_TRANSFER_DOWNLOAD:
+ break;
+
+ case PAKFIRE_TRANSFER_UPLOAD:
+ // Let cURL know that we are uploading things
+ r = curl_easy_setopt(transfer->handle, CURLOPT_UPLOAD, 1L);
+ if (r) {
+ CTX_ERROR(downloader->ctx, "Could not enable upload\n");
+ return r;
+ }
+
+ // Tell it the expected upload size
+ if (transfer->expected_size) {
+ r = curl_easy_setopt(transfer->handle,
+ CURLOPT_INFILESIZE_LARGE, (curl_off_t)transfer->expected_size);
+ if (r) {
+ CTX_ERROR(downloader->ctx, "Could not set upload size\n");
+ return r;
+ }
+ }
+ break;
+ }
+
// If we do not have an output file, we will create a temporary file
if (!transfer->f) {
r = pakfire_downloader_transfer_prepare_tmpfile(transfer);