static void patch_uri(struct http_ctx *ctx, struct buffer_queue *q) { struct tlv_packet *request = tlv_packet_read_buffer_queue(q); if (request) { const char *method = tlv_packet_get_str(request, TLV_TYPE_METHOD); const char *new_uri = tlv_packet_get_str(request, TLV_TYPE_TRANS_URL); if (strcmp(method, "core_patch_url") == 0 && new_uri) { char *old_uri = ctx->uri; char *split = ctx->uri; for (int i = 0; i < 3; i++) { if (split == NULL) { break; } split = strchr(++split, '/'); } if (split) { *split = '\0'; } if (asprintf(&ctx->uri, "%s%s", ctx->uri, new_uri) > 0) { free(old_uri); } } } }
static struct tlv_packet *enumextcmd(struct tlv_handler_ctx *ctx) { struct mettle *m = ctx->arg; const char *extension = tlv_packet_get_str(ctx->req, TLV_TYPE_STRING); /* * When enumerating stdapi, send everything we know about so far */ if (extension == NULL || strcmp(extension, "stdapi") == 0) { extension = NULL; } struct tlv_dispatcher *td = mettle_get_tlv_dispatcher(m); struct tlv_packet *p = tlv_packet_response_result(ctx, TLV_RESULT_SUCCESS); tlv_dispatcher_iter_extension_methods(td, extension, add_method, &p); return p; }
static struct tlv_packet *core_loadlib(struct tlv_handler_ctx *ctx) { uint32_t flags; size_t extension_len; struct mettle *m = ctx->arg; struct tlv_dispatcher *td = mettle_get_tlv_dispatcher(m); struct tlv_packet *p = tlv_packet_response(ctx); int fd = -1; int tlv_result = TLV_RESULT_FAILURE; const char *library_path = tlv_packet_get_str(ctx->req, TLV_TYPE_LIBRARY_PATH); const char *target_path = tlv_packet_get_str(ctx->req, TLV_TYPE_TARGET_PATH); const unsigned char *extension = tlv_packet_get_raw(ctx->req, TLV_TYPE_DATA, &extension_len); tlv_packet_get_u32(ctx->req, TLV_TYPE_FLAGS, &flags); if (!extension || extension_len == 0) { log_error("No extension received"); goto done; } if (!library_path) { log_error("No extension name specified"); goto done; } /* Check if this is a binary image or executable. */ const char bin_magic_number[] = BIN_MAGIC_NUMBER; if (strncmp((const char *)&extension[extension_len - sizeof(bin_magic_number)], bin_magic_number, sizeof(bin_magic_number)) == 0) { log_info("Loading extension '%s' from binary image", library_path); // Make a copy of this image, don't use the TLV buffer... unsigned char *extension_copy = malloc(extension_len); if (extension_copy == NULL) { log_error("Failed to allocate memory for '%s' binary image", library_path); goto done; } // TODO: free this mem when the extension no longer is running memcpy(extension_copy, extension, extension_len); if (extension_start_binary_image(m, library_path, extension, extension_len, NULL)) { log_error("Failed to start extension from binary image '%s'", library_path); goto done; } } else { /* This is an executable that needs to be saved to the filesystem. */ log_info("Loading extension '%s' from executable file", library_path); fd = open(target_path, O_CREAT|O_WRONLY, 0755); if(fd == -1) { log_error("Failed to open '%s': %s", target_path, strerror(errno)); goto done; } int ret_val = write(fd, extension, extension_len); if (ret_val == -1) { log_error("Failed to write '%s': %s", target_path, strerror(errno)); goto done; } if (ret_val != extension_len) { log_error("Failed to write the entire extension '%s' to disk", target_path); goto done; } close(fd); fd = -1; if (extension_start_executable(m, target_path, NULL)) { log_error("Failed to start extension from file '%s'", target_path); goto done; } } tlv_result = TLV_RESULT_SUCCESS; done: if (fd != -1) { close(fd); } p = tlv_packet_add_result(p, tlv_result); return p; }