return r;
}
-static int pakfire_buildservice_handle_error(struct pakfire_buildservice* service,
- struct pakfire_xfer* xfer, const struct json_object* error) {
- struct json_object* message = NULL;
- struct json_object* code = NULL;
- const char* m = NULL;
- unsigned int c = 0;
-
- // Fetch the URL
- const char* url = pakfire_xfer_get_effective_url(xfer);
-
- // Fetch the code
- if (!json_object_object_get_ex(error, "code", &code))
- return -EBADMSG;
-
- // Check if the code is an integer
- if (!json_object_is_type(code, json_type_int))
- return -EBADMSG;
-
- // Fetch the message
- if (!json_object_object_get_ex(error, "message", &message))
- return -EBADMSG;
-
- // Check if the message is a string
- if (!json_object_is_type(message, json_type_string))
- return -EBADMSG;
-
- c = json_object_get_uint64(code);
- m = json_object_get_string(message);
-
- // Log the error
- CTX_ERROR(service->ctx, "%s responded with error %u (%s):\n %s\n",
- url, c, strerror(c), m);
-
- return -c;
-}
-
-/*
- This function parses an API response
-*/
-static int pakfire_buildservice_parse_response(struct pakfire_buildservice* service,
- struct pakfire_xfer* xfer, const char* buffer, const size_t length,
- struct json_object** object) {
- struct json_object* error = NULL;
- struct json_object* o = NULL;
- int r;
-
- // Check if we received any data
- if (!length) {
- CTX_ERROR(service->ctx, "Received an empty response\n");
- r = -EBADMSG;
- goto ERROR;
- }
-
- // XXX Maybe fetch the parser's error message here?!
-
- // Parse the buffer
- o = pakfire_json_parse(service->ctx, buffer, length);
- if (!o) {
- CTX_ERROR(service->ctx, "Could not parse the response\n");
- r = -EBADMSG;
- goto ERROR;
- }
-
- // Check if the response is a dictionary
- if (!json_object_is_type(o, json_type_object)) {
- CTX_ERROR(service->ctx, "The received object is not a JSON dict\n");
- r = -EBADMSG;
- goto ERROR;
- }
-
- // Fetch error
- r = json_object_object_get_ex(o, "error", &error);
- if (r) {
- r = pakfire_buildservice_handle_error(service, xfer, error);
- goto ERROR;
- }
-
- // Return the object
- *object = o;
-
- return 0;
-
-ERROR:
- if (o)
- json_object_put(o);
-
- return r;
-}
-
// Build
int pakfire_buildservice_build(struct pakfire_buildservice* service, const char* upload,
const char* repo, const char** arches, int flags) {
struct pakfire_xfer* xfer = NULL;
- struct json_object* response = NULL;
- char* buffer = NULL;
- size_t length = 0;
int r;
// Create a new xfer
goto ERROR;
}
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, NULL);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
ERROR:
if (xfer)
pakfire_xfer_unref(xfer);
- if (response)
- json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
struct json_object* id = NULL;
const char* __id = NULL;
char* hexdigest = NULL;
- char* buffer = NULL;
- size_t length = 0;
struct stat stat;
int r;
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, &response);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
// Fetch the ID
r = json_object_object_get_ex(response, "id", &id);
if (r == 0) {
json_object_put(response);
if (hexdigest)
free(hexdigest);
- if (buffer)
- free(buffer);
return r;
}
static int pakfire_buildservice_upload_payload(struct pakfire_buildservice* service,
const char* filename, const char* uuid, FILE* f) {
struct pakfire_xfer* xfer = NULL;
- struct json_object* response = NULL;
- char* buffer = NULL;
- size_t length = 0;
char url[PATH_MAX];
int r;
if (r)
goto ERROR;
- // Set the output buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, 0);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, NULL);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
ERROR:
if (xfer)
pakfire_xfer_unref(xfer);
- if (response)
- json_object_put(response);
return r;
}
struct pakfire_xfer* xfer = NULL;
struct json_object* response = NULL;
struct json_object* uploads = NULL;
- char* buffer = NULL;
- size_t length = 0;
int r;
// Create a new xfer
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, &response);
if (r)
goto ERROR;
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
- if (r)
- goto ERROR;
-
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
// Fetch the uploads
uploads = json_object_object_get(response, "uploads");
if (!uploads) {
pakfire_xfer_unref(xfer);
if (response)
json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
struct pakfire_buildservice* service, const char* uuid) {
struct pakfire_xfer* xfer = NULL;
struct json_object* response = NULL;
- char* buffer = NULL;
- size_t length = 0;
char url[PATH_MAX];
int r;
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, &response);
if (r)
goto ERROR;
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
- if (r)
- goto ERROR;
-
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
ERROR:
if (xfer)
pakfire_xfer_unref(xfer);
if (response)
json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
struct json_object* response = NULL;
struct json_object* repos = NULL;
char url[PATH_MAX];
- char* buffer = NULL;
- size_t length = 0;
int r;
// Check inputs
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, &response);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
// Fetch the repos
if (!json_object_object_get_ex(response, "repos", &repos)) {
CTX_ERROR(service->ctx, "Malformed response\n");
pakfire_xfer_unref(xfer);
if (response)
json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
struct pakfire_xfer* xfer = NULL;
struct json_object* response = NULL;
char url[PATH_MAX];
- char* buffer = NULL;
- size_t length = 0;
int r;
// Check inputs
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, &response);
if (r)
goto ERROR;
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
- if (r)
- goto ERROR;
-
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
// Return the pointer
*p = json_object_get(response);
pakfire_xfer_unref(xfer);
if (response)
json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
struct pakfire_xfer* xfer = NULL;
struct json_object* response = NULL;
char url[PATH_MAX];
- char* buffer = NULL;
- size_t length = 0;
int r;
// Check inputs
goto ERROR;
}
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, &response);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
// Return the pointer
if (p)
*p = json_object_get(response);
pakfire_xfer_unref(xfer);
if (response)
json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
PAKFIRE_EXPORT int pakfire_buildservice_delete_repo(struct pakfire_buildservice* service,
const char* distro, const char* name) {
struct pakfire_xfer* xfer = NULL;
- struct json_object* response = NULL;
- char* buffer = NULL;
- size_t length = 0;
char url[PATH_MAX];
int r;
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, NULL);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
ERROR:
if (xfer)
pakfire_xfer_unref(xfer);
- if (response)
- json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
int r;
struct pakfire_xfer* xfer = NULL;
- json_object* response = NULL;
- char* buffer = NULL;
- size_t length = 0;
// Fetch the distro
const struct pakfire_distro* distro = pakfire_ctx_get_distro(service->ctx);
if (r)
goto ERROR;
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, NULL);
if (r)
goto ERROR;
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
- if (r)
- goto ERROR;
-
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
ERROR:
if (xfer)
pakfire_xfer_unref(xfer);
- if (response)
- json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
const char* uuid, int success, const char* logfile, const char** packages) {
struct pakfire_xfer* xfer = NULL;
char url[PATH_MAX];
- char* buffer = NULL;
- size_t length = 0;
int r;
- struct json_object* response = NULL;
-
unsigned int num_packages = 0;
// Count packages
goto ERROR;
}
- // Write the response to the buffer
- r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
- if (r)
- goto ERROR;
-
- // Run the xfer
- r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ // Send the request
+ r = pakfire_xfer_run_api_request(xfer, NULL);
if (r)
goto ERROR;
- // Parse the response
- r = pakfire_buildservice_parse_response(service, xfer, buffer, length, &response);
- if (r) {
- CTX_ERROR(service->ctx, "Could not parse the response: %s\n", strerror(-r));
- goto ERROR;
- }
-
ERROR:
if (xfer)
pakfire_xfer_unref(xfer);
- if (response)
- json_object_put(response);
- if (buffer)
- free(buffer);
return r;
}
#include <curl/curl.h>
+#include <json.h>
+
#include <openssl/err.h>
#include <openssl/evp.h>
return r;
}
+static void pakfire_xfer_reset_output(struct pakfire_xfer* xfer) {
+ if (xfer->fin) {
+ fclose(xfer->fin);
+ xfer->fin = NULL;
+ }
+}
+
int pakfire_xfer_set_output(struct pakfire_xfer* xfer, FILE* f) {
+ pakfire_xfer_reset_output(xfer);
+
+ // Store the new stream
xfer->fin = f;
return 0;
return r;
}
+
+static int pakfire_xfer_handle_api_error(
+ struct pakfire_xfer* xfer, const struct json_object* error) {
+ struct json_object* message = NULL;
+ struct json_object* code = NULL;
+ const char* m = NULL;
+ unsigned int c = 0;
+
+ // Fetch the URL
+ const char* url = pakfire_xfer_get_effective_url(xfer);
+
+ // Fetch the code
+ if (!json_object_object_get_ex(error, "code", &code))
+ return -EBADMSG;
+
+ // Check if the code is an integer
+ if (!json_object_is_type(code, json_type_int))
+ return -EBADMSG;
+
+ // Fetch the message
+ if (!json_object_object_get_ex(error, "message", &message))
+ return -EBADMSG;
+
+ // Check if the message is a string
+ if (!json_object_is_type(message, json_type_string))
+ return -EBADMSG;
+
+ c = json_object_get_uint64(code);
+ m = json_object_get_string(message);
+
+ // Log the error
+ CTX_ERROR(xfer->ctx, "%s responded with error %u (%s):\n %s\n",
+ url, c, strerror(c), m);
+
+ return -c;
+}
+
+/*
+ This function parses an API response
+*/
+static int pakfire_xfer_parse_api_response(struct pakfire_xfer* xfer,
+ const char* buffer, const size_t length, struct json_object** object) {
+ struct json_object* error = NULL;
+ struct json_object* o = NULL;
+ int r;
+
+ // Check if we received any data
+ if (!length) {
+ CTX_ERROR(xfer->ctx, "Received an empty response\n");
+ r = -EBADMSG;
+ goto ERROR;
+ }
+
+ // XXX Maybe fetch the parser's error message here?!
+
+ // Parse the buffer
+ o = pakfire_json_parse(xfer->ctx, buffer, length);
+ if (!o) {
+ CTX_ERROR(xfer->ctx, "Could not parse the response\n");
+ r = -EBADMSG;
+ goto ERROR;
+ }
+
+ // Check if the response is a dictionary
+ if (!json_object_is_type(o, json_type_object)) {
+ CTX_ERROR(xfer->ctx, "The received object is not a JSON dict\n");
+ r = -EBADMSG;
+ goto ERROR;
+ }
+
+ // Fetch error
+ r = json_object_object_get_ex(o, "error", &error);
+ if (r) {
+ r = pakfire_xfer_handle_api_error(xfer, error);
+ goto ERROR;
+ }
+
+ // Return the object
+ if (object)
+ *object = json_object_get(o);
+
+ERROR:
+ if (o)
+ json_object_put(o);
+
+ return r;
+}
+
+static int pakfire_xfer_run_api_request_once(struct pakfire_xfer* xfer, struct json_object** response) {
+ char* buffer = NULL;
+ size_t length = 0;
+ int r;
+
+ // Write the response to the buffer
+ r = pakfire_xfer_set_output_buffer(xfer, &buffer, &length);
+ if (r)
+ goto ERROR;
+
+ // Run the xfer
+ r = pakfire_xfer_run(xfer, PAKFIRE_XFER_NO_PROGRESS);
+ if (r)
+ goto ERROR;
+
+ // Parse the response
+ r = pakfire_xfer_parse_api_response(xfer, buffer, length, response);
+ if (r) {
+ CTX_ERROR(xfer->ctx, "Could not parse the API response: %s\n", strerror(-r));
+ goto ERROR;
+ }
+
+ERROR:
+ // Reset the output stream
+ pakfire_xfer_reset_output(xfer);
+
+ if (buffer)
+ free(buffer);
+
+ return r;
+}
+
+/*
+ This function sends a request and automatically parses the response.
+ The response might optionally be returned if response is not NULL.
+*/
+int pakfire_xfer_run_api_request(struct pakfire_xfer* xfer, struct json_object** response) {
+ int r;
+
+ // Loop indefinitely...
+ for (;;) {
+ r = pakfire_xfer_run_api_request_once(xfer, response);
+ switch (r) {
+ // XXX need to catch errors and act accordingly
+
+ default:
+ return r;
+ }
+ }
+
+ return 0;
+}