diff --git a/rhizome.c b/rhizome.c index 96365038..69768b83 100644 --- a/rhizome.c +++ b/rhizome.c @@ -41,60 +41,63 @@ int rhizome_enabled() return rhizome_enabled_flag; } -/* Import a bundle from the inbox folder. The bundle is contained a pair of files, one containing - the manifest and the optional other containing the payload. - - The logic is all in rhizome_add_manifest(). This function just wraps that function and manages - file and object buffers and lifetimes. +/* Import a bundle from a pair of files, one containing the manifest and the optional other + containing the payload. The logic is all in rhizome_bundle_import(). This function just wraps + that function and manages file and object buffers and lifetimes. */ -int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out, - const char *manifest_path, int ttl) +int rhizome_bundle_import_files(const char *manifest_path, const char *payload_path, int ttl) { if (debug & DEBUG_RHIZOME) - DEBUGF("rhizome_bundle_import(m_in=%p, m_out=%p, manifest_path=%s, ttl=%d)", - m_in, m_out, + DEBUGF("(manifest_path=%s, payload_path=%s, ttl=%d)", manifest_path ? alloca_str_toprint(manifest_path) : "NULL", + payload_path ? alloca_str_toprint(payload_path) : "NULL", ttl ); - if (m_out) - *m_out = NULL; /* Read manifest file if no manifest was given */ - rhizome_manifest *m = m_in; - if (!m_in) { - if (!manifest_path) - return WHY("No manifest supplied"); - m = rhizome_new_manifest(); - if (!m) - return WHY("Out of manifests"); - if (rhizome_read_manifest_file(m, manifest_path, 0 /* file not buffer */) == -1) { - rhizome_manifest_free(m); - return WHY("Could not read manifest file"); - } else if (rhizome_manifest_verify(m)) { - rhizome_manifest_free(m); - return WHY("Could not verify manifest file"); - } + if (!manifest_path) + return WHY("No manifest supplied"); + int ret = 0; + rhizome_manifest *m = rhizome_new_manifest(); + if (!m) + ret = WHY("Out of manifests"); + else if (rhizome_read_manifest_file(m, manifest_path, 0 /* file not buffer */) == -1) + ret = WHY("Could not read manifest file"); + else if (rhizome_manifest_verify(m)) + ret = WHY("Verification of manifest file failed"); + else { + m->dataFileName = strdup(payload_path); + if (rhizome_manifest_check_file(m)) + ret = WHY("Payload does not belong to manifest"); + else + ret = rhizome_bundle_import(m, ttl); } + if (m) + rhizome_manifest_free(m); + return ret; +} + +/* Import a bundle from a finalised manifest struct. The dataFileName element must give the path + of a readable file containing the payload unless the payload is null (zero length). The logic is + all in rhizome_add_manifest(). This function just wraps that function and manages object buffers + and lifetimes. +*/ + +int rhizome_bundle_import(rhizome_manifest *m, int ttl) +{ + if (debug & DEBUG_RHIZOME) + DEBUGF("(m=%p, ttl=%d)", m, ttl); /* Add the manifest and its payload to the Rhizome database. */ if (m->fileLength > 0 && !(m->dataFileName && m->dataFileName[0])) return WHY("Missing data file name"); if (rhizome_manifest_check_file(m)) return WHY("File does not belong to manifest"); int ret = rhizome_manifest_check_duplicate(m, NULL); - if (ret == 0) + if (ret == 0) { ret = rhizome_add_manifest(m, ttl); - if (ret == -1) { - WHY("rhizome_add_manifest() failed"); - } else { - if (manifest_path && rhizome_write_manifest_file(m, manifest_path)) - ret = WHYF("Could not write %s", manifest_path); + if (ret == -1) + WHY("rhizome_add_manifest() failed"); } - /* If the manifest structure was allocated in this function, and it is not being returned to the - caller, then this function is responsible for freeing it */ - if (m_out) - *m_out = m; - else if (!m_in) - rhizome_manifest_free(m); return ret; } diff --git a/rhizome.h b/rhizome.h index 10580ac8..8eda18f6 100644 --- a/rhizome.h +++ b/rhizome.h @@ -209,7 +209,8 @@ int rhizome_store_bundle(rhizome_manifest *m); int rhizome_manifest_add_group(rhizome_manifest *m,char *groupid); int rhizome_clean_payload(const char *fileidhex); int rhizome_store_file(rhizome_manifest *m,const unsigned char *key); -int rhizome_bundle_import(rhizome_manifest *m_in, rhizome_manifest **m_out, const char *manifest_path, int ttl); +int rhizome_bundle_import_files(const char *manifest_path, const char *payload_path, int ttl); +int rhizome_bundle_import(rhizome_manifest *m, int ttl); int rhizome_manifest_verify(rhizome_manifest *m); int rhizome_manifest_check_sanity(rhizome_manifest *m_in); diff --git a/rhizome_direct_http.c b/rhizome_direct_http.c index e650dc29..836c13da 100644 --- a/rhizome_direct_http.c +++ b/rhizome_direct_http.c @@ -45,23 +45,13 @@ int rhizome_direct_form_received(rhizome_http_request *r) if (!strcmp(r->path,"/rhizome/import")) { switch(r->fields_seen) { case RD_MIME_STATE_MANIFESTHEADERS | RD_MIME_STATE_DATAHEADERS: { - /* A bundle to import */ - strbuf cmd = strbuf_alloca(1024); - strbuf_sprintf(cmd, - "servald rhizome import bundle rhizomedirect.%d.data rhizomedirect.%d.manifest", - r->alarm.poll.fd, r->alarm.poll.fd - ); - DEBUGF("system(\"%s\")", strbuf_str(cmd)); - int status = system(strbuf_str(cmd)); - /* clean up after ourselves */ + /* Got a bundle to import */ + strbuf manifest_path = strbuf_alloca(50); + strbuf payload_path = strbuf_alloca(50); + strbuf_sprintf(manifest_path, "rhizomedirect.%d.manifest", r->alarm.poll.fd); + strbuf_sprintf(payload_path, "rhizomedirect.%d.data", r->alarm.poll.fd); + int ret = rhizome_bundle_import_files(strbuf_str(manifest_path), strbuf_str(payload_path), 1); // ttl = 1 rhizome_direct_clear_temporary_files(r); - if (status == -1) { - WHYF_perror("system(\"%s\")", strbuf_str(cmd)); - return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command not executed."); - } - strbuf st = strbuf_alloca(100); - strbuf_append_exit_status(st, status); - DEBUGF("Import command %s", strbuf_str(st)); /* report back to caller. 200 = ok, which is probably appropriate for when we already had the bundle. 201 = content created, which is probably appropriate for when we successfully @@ -70,18 +60,13 @@ int rhizome_direct_form_received(rhizome_http_request *r) the import fails due to malformed data etc. (should probably also indicate if we have a newer version if possible) */ - if (WIFEXITED(status)) { - switch (WEXITSTATUS(status)) { - case 0: - return rhizome_server_simple_http_response(r, 201, "Bundle succesfully imported."); - case 1: - return rhizome_server_simple_http_response(r, 200, "Bundle already imported."); - default: - return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command failed."); - } + switch (ret) { + case 0: + return rhizome_server_simple_http_response(r, 201, "Bundle succesfully imported."); + case 2: + return rhizome_server_simple_http_response(r, 200, "Bundle already imported."); } - WHY("should not reach here"); - return rhizome_server_simple_http_response(r, 500, "Server error: Internal bug."); + return rhizome_server_simple_http_response(r, 500, "Server error: Rhizome import command failed."); } break; default: diff --git a/rhizome_fetch.c b/rhizome_fetch.c index bde17595..10b01649 100644 --- a/rhizome_fetch.c +++ b/rhizome_fetch.c @@ -388,7 +388,7 @@ void rhizome_import_received_bundle(struct rhizome_manifest *m) DEBUGF("manifest len=%d has %d signatories", m->manifest_bytes, m->sig_count); dump("manifest", m->manifestdata, m->manifest_all_bytes); } - rhizome_bundle_import(m, NULL, NULL, m->ttl - 1 /* TTL */); + rhizome_bundle_import(m, m->ttl - 1 /* TTL */); } /* Verifies manifests as late as possible to avoid wasting time. */ @@ -707,7 +707,7 @@ int rhizome_queue_manifest_import(rhizome_manifest *m, struct sockaddr_in *peeri } else { if (debug & DEBUG_RHIZOME_RX) DEBUGF("We already have the file for this manifest; importing from manifest alone."); - rhizome_bundle_import(m, NULL, NULL, m->ttl-1); + rhizome_bundle_import(m, m->ttl-1); } } diff --git a/tests/rhizomeprotocol b/tests/rhizomeprotocol index 0928f6e0..50ffddf3 100755 --- a/tests/rhizomeprotocol +++ b/tests/rhizomeprotocol @@ -317,7 +317,7 @@ test_HttpImport() { "$addr_localhost:$PORTA/rhizome/import" tfw_cat http.headers http.output executeOk_servald rhizome list '' - assert_rhizome_list README.WHYNOTSIPS + assert_rhizome_list README.WHYNOTSIPS! } doc_HttpAddLocal="Add file locally using HTTP, returns manifest"