From 181d1363f14e506a6068a71e0da1acc0ed2c1bd1 Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Wed, 19 Dec 2012 16:16:49 +1030 Subject: [PATCH] Migrate command line import to new storage api --- commandline.c | 107 ++++++++++++++++++++++++++++++--------------- rhizome.h | 2 + rhizome_database.c | 68 ---------------------------- rhizome_store.c | 67 ++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 104 deletions(-) diff --git a/commandline.c b/commandline.c index 0c397f45..5119bf57 100644 --- a/commandline.c +++ b/commandline.c @@ -1214,41 +1214,8 @@ int app_rhizome_add_file(int argc, const char *const *argv, const struct command m->payloadEncryption=0; rhizome_manifest_set_ll(m,"crypt",m->payloadEncryption?1:0); - m->fileLength = 0; - if (filepath[0]) { - struct stat stat; - if (lstat(filepath,&stat)) - return WHYF("Could not stat() payload file '%s'",filepath); - m->fileLength = stat.st_size; - } - rhizome_manifest_set_ll(m, "filesize", m->fileLength); - - if (m->fileLength){ - // Stream the file directly into the database, encrypting & hashing as we go. - struct rhizome_write write; - bzero(&write, sizeof(write)); - - if (rhizome_open_write(&write, NULL, m->fileLength, RHIZOME_PRIORITY_DEFAULT)) - return -1; - - if (rhizome_write_file(&write, filepath)){ - rhizome_fail_write(&write); - return -1; - } - - if (rhizome_finish_write(&write)) - return -1; - - m->fileHashedP = 1; - strlcpy(m->fileHexHash, write.id, SHA512_DIGEST_STRING_LENGTH); - rhizome_manifest_set(m, "filehash", m->fileHexHash); - - } else { - m->fileLength = 0; - m->fileHexHash[0] = '\0'; - rhizome_manifest_del(m, "filehash"); - m->fileHashedP = 0; - } + if (rhizome_add_file(m, filepath)) + return -1; /* Add the manifest and its associated file to the Rhizome database, generating an "id" in the process. @@ -1349,7 +1316,75 @@ int app_rhizome_import_bundle(int argc, const char *const *argv, const struct co cli_arg(argc, argv, o, "manifestpath", &manifestpath, NULL, ""); if (rhizome_opendb() == -1) return -1; - int status=rhizome_import_from_files(manifestpath,filepath); + + rhizome_manifest *m = rhizome_new_manifest(); + if (!m) + return WHY("Out of manifests."); + int status=0; + + if (rhizome_read_manifest_file(m, manifestpath, 0) == -1) { + status = WHY("could not read manifest file"); + goto cleanup; + } + if (rhizome_manifest_verify(m)){ + status = WHY("could not verify manifest"); + goto cleanup; + } + + /* Make sure we store signatures */ + // TODO, why do we need this? Why isn't the state correct from rhizome_read_manifest_file? + // This feels like a hack... + m->manifest_bytes=m->manifest_all_bytes; + + status = rhizome_import_file(m, filepath); + if (status<0) + goto cleanup; + + status = rhizome_manifest_check_duplicate(m, NULL); + if (status<0) + goto cleanup; + + if (status==0){ + if (rhizome_add_manifest(m, 1) == -1) { // ttl = 1 + status = WHY("rhizome_add_manifest() failed"); + goto cleanup; + } + }else + INFO("Duplicate found in store"); + + const char *service = rhizome_manifest_get(m, "service", NULL, 0); + if (service) { + cli_puts("service"); + cli_delim(":"); + cli_puts(service); + cli_delim("\n"); + } + { + cli_puts("manifestid"); + cli_delim(":"); + cli_puts(alloca_tohex(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES)); + cli_delim("\n"); + } + cli_puts("filesize"); + cli_delim(":"); + cli_printf("%lld", m->fileLength); + cli_delim("\n"); + if (m->fileLength != 0) { + cli_puts("filehash"); + cli_delim(":"); + cli_puts(m->fileHexHash); + cli_delim("\n"); + } + const char *name = rhizome_manifest_get(m, "name", NULL, 0); + if (name) { + cli_puts("name"); + cli_delim(":"); + cli_puts(name); + cli_delim("\n"); + } + +cleanup: + rhizome_manifest_free(m); return status; } diff --git a/rhizome.h b/rhizome.h index 212971b3..0269f666 100644 --- a/rhizome.h +++ b/rhizome.h @@ -617,5 +617,7 @@ int rhizome_flush(struct rhizome_write *write); int rhizome_write_file(struct rhizome_write *write, const char *filename); int rhizome_fail_write(struct rhizome_write *write); int rhizome_finish_write(struct rhizome_write *write); +int rhizome_import_file(rhizome_manifest *m, const char *filepath); +int rhizome_add_file(rhizome_manifest *m, const char *filepath); #endif //__SERVALDNA__RHIZOME_H diff --git a/rhizome_database.c b/rhizome_database.c index 2bab92b0..c8b2aade 100644 --- a/rhizome_database.c +++ b/rhizome_database.c @@ -1625,71 +1625,3 @@ int rhizome_retrieve_file(const char *fileid, const char *filepath, const unsign sqlite3_finalize(statement); return ret; } - -int rhizome_import_from_files(const char *manifestpath,const char *filepath) -{ - rhizome_manifest *m = rhizome_new_manifest(); - if (!m) - return WHY("Out of manifests."); - int status = -1; - if (rhizome_read_manifest_file(m, manifestpath, 0) == -1) { - status = WHY("could not read manifest file"); - } else if (rhizome_manifest_verify(m) == -1) { - status = WHY("Could not verify manifest file."); - } else { - /* Make sure we store signatures */ - m->manifest_bytes=m->manifest_all_bytes; - - /* Add the manifest and its associated file to the Rhizome database. */ - m->dataFileName = strdup(filepath); - if (rhizome_manifest_check_file(m)) - status = WHY("file does not belong to manifest"); - else { - int ret = rhizome_manifest_check_duplicate(m, NULL); - if (ret == -1) - status = WHY("rhizome_manifest_check_duplicate() failed"); - else if (ret) { - INFO("Duplicate found in store"); - status = 1; - } else if (rhizome_add_manifest(m, 1) == -1) { // ttl = 1 - status = WHY("rhizome_add_manifest() failed"); - } else { - status = 0; - } - if (status != -1) { - const char *service = rhizome_manifest_get(m, "service", NULL, 0); - if (service) { - cli_puts("service"); - cli_delim(":"); - cli_puts(service); - cli_delim("\n"); - } - { - cli_puts("manifestid"); - cli_delim(":"); - cli_puts(alloca_tohex(m->cryptoSignPublic, RHIZOME_MANIFEST_ID_BYTES)); - cli_delim("\n"); - } - cli_puts("filesize"); - cli_delim(":"); - cli_printf("%lld", m->fileLength); - cli_delim("\n"); - if (m->fileLength != 0) { - cli_puts("filehash"); - cli_delim(":"); - cli_puts(m->fileHexHash); - cli_delim("\n"); - } - const char *name = rhizome_manifest_get(m, "name", NULL, 0); - if (name) { - cli_puts("name"); - cli_delim(":"); - cli_puts(name); - cli_delim("\n"); - } - } - } - } - rhizome_manifest_free(m); - return status; -} diff --git a/rhizome_store.c b/rhizome_store.c index 7ddc1db6..05ad04b9 100644 --- a/rhizome_store.c +++ b/rhizome_store.c @@ -237,3 +237,70 @@ failure: rhizome_fail_write(write); return -1; } + +// import a file for an existing bundle with a known file hash +int rhizome_import_file(rhizome_manifest *m, const char *filepath) +{ + if (m->fileLength<=0) + return 0; + + /* Import the file first, checking the hash as we go */ + struct rhizome_write write; + bzero(&write, sizeof(write)); + + int ret=rhizome_open_write(&write, m->fileHexHash, m->fileLength, RHIZOME_PRIORITY_DEFAULT); + if (ret!=0) + return ret; + + // file payload is not in the store yet + if (rhizome_write_file(&write, filepath)){ + rhizome_fail_write(&write); + return -1; + } + + if (rhizome_finish_write(&write)) + return -1; + return 0; +} + +// import a file for a new bundle with an unknown file hash +// update the manifest with the details of the file +int rhizome_add_file(rhizome_manifest *m, const char *filepath) +{ + m->fileLength = 0; + if (filepath[0]) { + struct stat stat; + if (lstat(filepath,&stat)) + return WHYF("Could not stat() payload file '%s'",filepath); + m->fileLength = stat.st_size; + } + + rhizome_manifest_set_ll(m, "filesize", m->fileLength); + + if (m->fileLength == 0){ + m->fileHexHash[0] = '\0'; + rhizome_manifest_del(m, "filehash"); + m->fileHashedP = 0; + return 0; + } + + // Stream the file directly into the database, encrypting & hashing as we go. + struct rhizome_write write; + bzero(&write, sizeof(write)); + + if (rhizome_open_write(&write, NULL, m->fileLength, RHIZOME_PRIORITY_DEFAULT)) + return -1; + + if (rhizome_write_file(&write, filepath)){ + rhizome_fail_write(&write); + return -1; + } + + if (rhizome_finish_write(&write)) + return -1; + + m->fileHashedP = 1; + strlcpy(m->fileHexHash, write.id, SHA512_DIGEST_STRING_LENGTH); + rhizome_manifest_set(m, "filehash", m->fileHexHash); + return 0; +}