return r;
}
+
+int pakfire_b64decode(struct pakfire* pakfire, void** output, size_t* length,
+ const char* buffer) {
+ char error[OPENSSL_ERROR_MAX];
+ char chunk[1024];
+ BIO* b64 = NULL;
+ BIO* bio = NULL;
+ char* p = NULL;
+ int r;
+
+ // Reset length
+ *length = 0;
+
+ // Initialize the base64 decoder
+ b64 = BIO_new(BIO_f_base64());
+ if (!b64) {
+ ERR_error_string_n(ERR_get_error(), error, sizeof(error));
+
+ ERROR(pakfire, "Could not initialize the base64 decoder: %s\n", error);
+ r = 1;
+ goto ERROR;
+ }
+
+ BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
+
+ // Initialize a memory buffer
+ bio = BIO_new_mem_buf(buffer, strlen(buffer));
+ if (!bio) {
+ ERR_error_string_n(ERR_get_error(), error, sizeof(error));
+
+ ERROR(pakfire, "Could not initialize memory buffer: %s\n", error);
+ r = 1;
+ goto ERROR;
+ }
+
+ // Connect both things
+ bio = BIO_push(b64, bio);
+
+ for (;;) {
+ // Read a chunk of data
+ ssize_t bytes_read = BIO_read(bio, chunk, sizeof(chunk));
+
+ // Handle any errors
+ if (bytes_read < 0) {
+ ERR_error_string_n(ERR_get_error(), error, sizeof(error));
+
+ ERROR(pakfire, "Could not read data: %s\n", error);
+ r = 1;
+ goto ERROR;
+
+ // Break if no more data could be read
+ } else if (bytes_read == 0) {
+ break;
+
+ // Handle the chunk
+ } else {
+ // Update total length of data
+ *length += bytes_read;
+
+ // Allocate an output buffer
+ p = realloc(p, *length);
+ if (!p) {
+ ERROR(pakfire, "Could not allocate buffer: %m\n");
+ r = 1;
+ goto ERROR;
+ }
+
+ // Copy the chunk
+ memcpy(p + *length - bytes_read, chunk, bytes_read);
+ }
+ }
+
+ // Set output pointer
+ *output = p;
+
+ // Success!
+ r = 0;
+
+ERROR:
+ if (r && p)
+ free(p);
+ if (bio)
+ BIO_free_all(bio);
+
+ return r;
+}
return EXIT_FAILURE;
}
+static int test_base64(const struct test* t) {
+ int r = EXIT_FAILURE;
+
+ const char data[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
+ char* base64 = NULL;
+ void* output = NULL;
+ size_t length = 0;
+
+ // Encode data as base64
+ ASSERT_SUCCESS(pakfire_b64encode(t->pakfire, &base64, data, sizeof(data)));
+
+ // Print the encoded data
+ printf("%s\n", base64);
+
+ // Decode the data
+ ASSERT_SUCCESS(pakfire_b64decode(t->pakfire, &output, &length, base64));
+
+ // Print the decoded data
+ printf("%.*s\n", length, output);
+
+ // Check that we encoded the correct amount of data
+ ASSERT_EQUALS(length, sizeof(data));
+
+ // Check that the output matches the input
+ ASSERT(memcmp(data, output, sizeof(data)) == 0);
+
+ // Everything passed
+ r = EXIT_SUCCESS;
+
+FAIL:
+ if (base64)
+ free(base64);
+
+ return r;
+}
+
int main(int argc, const char* argv[]) {
testsuite_add_test(test_basename);
testsuite_add_test(test_dirname);
testsuite_add_test(test_mkdir);
testsuite_add_test(test_path_match);
+ testsuite_add_test(test_base64);
return testsuite_run(argc, argv);
}