Append manifest into zip file comment

This commit is contained in:
Jeremy Lakeman 2016-03-30 15:32:50 +10:30
parent a5ff0ed2a3
commit 5636edfe20
7 changed files with 300 additions and 83 deletions

View File

@ -456,6 +456,13 @@ public class ServalDCommand
return result;
}
public static ManifestResult rhizomeImportZipBundle(File payloadFile) throws ServalDFailureException {
ManifestResult result = new ManifestResult();
result.setResult(command(result, "rhizome", "import", "bundle", "--zip-comment",
payloadFile.getAbsolutePath(), payloadFile.getAbsolutePath()));
return result;
}
public static ManifestResult rhizomeExtractBundle(BundleId manifestId, File manifestFile, File payloadFile) throws ServalDFailureException{
ManifestResult result = new ManifestResult();
result.setResult(command(result, "rhizome", "extract", "bundle",
@ -465,6 +472,15 @@ public class ServalDCommand
return result;
}
public static ManifestResult rhizomeExportZipBundle(BundleId manifestId, File payloadFile) throws ServalDFailureException{
ManifestResult result = new ManifestResult();
result.setResult(command(result, "rhizome", "export", "bundle", "--zip-comment",
manifestId.toHex(),
payloadFile.getAbsolutePath(),
payloadFile.getAbsolutePath()));
return result;
}
public static ManifestResult rhizomeExportManifest(BundleId manifestId, File manifestFile) throws ServalDFailureException{
ManifestResult result = new ManifestResult();
result.setResult(command(result, "rhizome", "export", "manifest",

221
rhizome.c
View File

@ -340,87 +340,184 @@ error:
* containing the payload. The work is all done by rhizome_bundle_import() and
* rhizome_store_manifest().
*/
enum rhizome_bundle_status rhizome_bundle_import_files(rhizome_manifest *m, rhizome_manifest **mout, const char *manifest_path, const char *filepath)
enum rhizome_bundle_status rhizome_bundle_import_files(rhizome_manifest *m, rhizome_manifest **mout, const char *manifest_path, const char *filepath, int zip_comment)
{
DEBUGF(rhizome, "(manifest_path=%s, filepath=%s)",
DEBUGF(rhizome, "(manifest_path=%s, filepath=%s, zip_comment=%d)",
manifest_path ? alloca_str_toprint(manifest_path) : "NULL",
filepath ? alloca_str_toprint(filepath) : "NULL");
filepath ? alloca_str_toprint(filepath) : "NULL",
zip_comment);
size_t buffer_len = 0;
int ret = 0;
// manifest has been appended to the end of the file.
if (strcmp(manifest_path, filepath)==0){
unsigned char marker[4];
FILE *f = fopen(filepath, "r");
if (f == NULL)
return WHYF_perror("Could not open manifest file %s for reading.", filepath);
if (fseek(f, -sizeof(marker), SEEK_END))
ret=WHY_perror("Unable to seek to end of file");
if (ret==0){
ret = fread(marker, 1, sizeof(marker), f);
if (ret==sizeof(marker))
ret=0;
else
ret=WHY_perror("Unable to read end of manifest marker");
}
if (ret==0){
if (marker[2]!=0x41 || marker[3]!=0x10)
ret=WHYF("Expected 0x4110 marker at end of file");
}
if (ret==0){
buffer_len = read_uint16(marker);
if (buffer_len < 1 || buffer_len > MAX_MANIFEST_BYTES)
ret=WHYF("Invalid manifest length %zu", buffer_len);
}
if (ret==0){
if (fseek(f, -(buffer_len+sizeof(marker)), SEEK_END))
ret=WHY_perror("Unable to seek to end of file");
}
if (ret == 0 && fread(m->manifestdata, buffer_len, 1, f) != 1) {
if (ferror(f))
ret = WHYF("fread(%p,%zu,1,%s) error", m->manifestdata, buffer_len, alloca_str_toprint(filepath));
else if (feof(f))
ret = WHYF("fread(%p,%zu,1,%s) hit end of file", m->manifestdata, buffer_len, alloca_str_toprint(filepath));
}
fclose(f);
} else {
ssize_t size = read_whole_file(manifest_path, m->manifestdata, sizeof m->manifestdata);
if (size == -1)
ret = -1;
buffer_len = (size_t) size;
enum rhizome_bundle_status ret;
int single_file = strcmp(manifest_path, filepath)==0;
int fd = open(manifest_path, O_RDONLY);
if (fd == -1)
return WHYF_perror("Could not open manifest file %s for reading.", filepath);
off_t file_len = lseek(fd, 0, SEEK_END);
if (file_len==-1){
ret=WHY_perror("Unable to determine file length");
goto end;
}
if (ret)
return ret;
m->manifest_all_bytes = buffer_len;
uint8_t buff[MAX_MANIFEST_BYTES + 22];
off_t read_len = sizeof buff;
if (read_len > file_len)
read_len = file_len;
if (lseek(fd, -read_len, SEEK_END)==-1){
ret=WHYF_perror("lseek(%d, %d, SEEK_END) - Failed to seek to near the end of %s, len %u", fd, (int)-read_len, manifest_path, (int)file_len);
goto end;
}
if (read(fd, buff, read_len)!=read_len){
ret=WHYF_perror("Failed to read %u bytes of the manifest", (int)read_len);
goto end;
}
uint8_t *manifest_ptr;
// manifest has been appended to the end of the file.
if (single_file){
if (zip_comment){
// scan backwards for EOCD marker 0x504b0506
uint8_t *EOCD = &buff[read_len - 22];
while(EOCD){
if (EOCD[0]==0x50 && EOCD[1]==0x4b && EOCD[2]==0x05 && EOCD[3]==0x06)
break;
EOCD--;
}
if (!EOCD){
ret=WHY("Expected zip EOCD marker 0x504b0506 near end of file");
goto end;
}
m->manifest_all_bytes = EOCD[20] | (EOCD[21]<<8);
manifest_ptr = &EOCD[22];
}else{
if (buff[read_len-2]!=0x41 || buff[read_len-1]!=0x10){
ret=WHYF("Expected 0x4110 marker at end of file");
goto end;
}
m->manifest_all_bytes = read_uint16(&buff[read_len-4]);
manifest_ptr = &buff[read_len - m->manifest_all_bytes - 4];
}
}else{
manifest_ptr = buff;
m->manifest_all_bytes = read_len;
}
if (m->manifest_all_bytes < 1 || m->manifest_all_bytes > MAX_MANIFEST_BYTES){
ret=WHYF("Invalid manifest length %zu", m->manifest_all_bytes);
goto end;
}
if (manifest_ptr < buff || manifest_ptr + m->manifest_all_bytes > buff + read_len){
ret=WHY("Invalid manifest offset");
goto end;
}
bcopy(manifest_ptr, m->manifestdata, m->manifest_all_bytes);
if ( rhizome_manifest_parse(m) == -1
|| !rhizome_manifest_validate(m)
|| !rhizome_manifest_verify(m)
)
return RHIZOME_BUNDLE_STATUS_INVALID;
enum rhizome_bundle_status status = rhizome_manifest_check_stored(m, mout);
if (status != RHIZOME_BUNDLE_STATUS_NEW)
return status;
enum rhizome_payload_status pstatus = rhizome_import_payload_from_file(m, filepath);
){
ret = RHIZOME_BUNDLE_STATUS_INVALID;
goto end;
}
ret = rhizome_manifest_check_stored(m, mout);
if (ret != RHIZOME_BUNDLE_STATUS_NEW)
goto end;
enum rhizome_payload_status pstatus = RHIZOME_PAYLOAD_STATUS_EMPTY;
if (m->filesize > 0){
if (single_file){
if (lseek(fd, 0, SEEK_SET)==-1){
ret=WHY_perror("Unable to seek to start of file");
goto end;
}
}else{
close(fd);
fd = open(filepath, O_RDONLY);
if (fd==-1)
return WHYF_perror("Could not open payload file %s for reading.", filepath);
}
/* Import the file, checking the hash as we go */
struct rhizome_write write;
bzero(&write, sizeof(write));
pstatus = rhizome_open_write(&write, &m->filehash, m->filesize);
if (pstatus == RHIZOME_PAYLOAD_STATUS_NEW){
off_t read_len = m->filesize;
uint8_t payload_buffer[RHIZOME_CRYPT_PAGE_SIZE];
if (zip_comment)
read_len -=2;
while(write.file_offset < (uint64_t)read_len){
size_t size = sizeof payload_buffer;
if (write.file_offset + size > (uint64_t)read_len)
size = read_len - write.file_offset;
ssize_t r = read(fd, payload_buffer, size);
if (r == -1) {
ret = WHYF_perror("read(%d,%p,%zu)", fd, payload_buffer, size);
rhizome_fail_write(&write);
goto end;
}
if ((size_t) r != size) {
ret = WHYF("file truncated - read(%d,%p,%zu) returned %zu", fd, payload_buffer, size, (size_t) r);
rhizome_fail_write(&write);
goto end;
}
if (r && rhizome_write_buffer(&write, payload_buffer, (size_t) r)) {
ret = -1;
rhizome_fail_write(&write);
goto end;
}
}
if (zip_comment){
uint8_t comment_len[2] = {0,0};
if (rhizome_write_buffer(&write, comment_len, sizeof comment_len)){
ret = -1;
rhizome_fail_write(&write);
goto end;
}
}
pstatus = rhizome_finish_write(&write);
}
}
switch (pstatus) {
case RHIZOME_PAYLOAD_STATUS_EMPTY:
case RHIZOME_PAYLOAD_STATUS_STORED:
case RHIZOME_PAYLOAD_STATUS_NEW:
if (rhizome_store_manifest(m) == -1)
return -1;
return status;
ret = -1;
break;
case RHIZOME_PAYLOAD_STATUS_TOO_BIG:
case RHIZOME_PAYLOAD_STATUS_EVICTED:
return RHIZOME_BUNDLE_STATUS_NO_ROOM;
ret = RHIZOME_BUNDLE_STATUS_NO_ROOM;
break;
case RHIZOME_PAYLOAD_STATUS_ERROR:
case RHIZOME_PAYLOAD_STATUS_CRYPTO_FAIL:
return -1;
ret = -1;
break;
case RHIZOME_PAYLOAD_STATUS_WRONG_SIZE:
case RHIZOME_PAYLOAD_STATUS_WRONG_HASH:
return RHIZOME_BUNDLE_STATUS_INCONSISTENT;
ret = RHIZOME_BUNDLE_STATUS_INCONSISTENT;
break;
default:
FATALF("rhizome_import_payload_from_file() returned status = %d", pstatus);
}
FATALF("rhizome_import_payload_from_file() returned status = %d", pstatus);
end:
close(fd);
return ret;
}
/* Sets the bundle key "BK" field of a manifest. Returns 1 if the field was set, 0 if not.

View File

@ -501,7 +501,7 @@ struct rhizome_bundle_result rhizome_manifest_add_file(int appending,
const char *file_path,
unsigned nassignments,
const struct rhizome_manifest_field_assignment *assignments);
int rhizome_bundle_import_files(rhizome_manifest *m, rhizome_manifest **m_out, const char *manifest_path, const char *filepath);
int rhizome_bundle_import_files(rhizome_manifest *m, rhizome_manifest **m_out, const char *manifest_path, const char *filepath, int zip_files);
int rhizome_manifest_set_name_from_path(rhizome_manifest *m, const char *filepath);
struct rhizome_bundle_result rhizome_fill_manifest(rhizome_manifest *m, const char *filepath, const sid_t *authorSidp);
@ -915,7 +915,7 @@ int rhizome_write_buffer(struct rhizome_write *write_state, uint8_t *buffer, siz
int rhizome_random_write(struct rhizome_write *write_state, uint64_t offset, uint8_t *buffer, size_t data_size);
enum rhizome_payload_status rhizome_write_open_manifest(struct rhizome_write *write, rhizome_manifest *m);
enum rhizome_payload_status rhizome_write_open_journal(struct rhizome_write *write, rhizome_manifest *m, uint64_t advance_by, uint64_t append_size);
int rhizome_write_file(struct rhizome_write *write, const char *filename);
int rhizome_write_file(struct rhizome_write *write, const char *filename, off_t offset, uint64_t length);
void rhizome_fail_write(struct rhizome_write *write);
enum rhizome_payload_status rhizome_finish_write(struct rhizome_write *write);
enum rhizome_payload_status rhizome_finish_store(struct rhizome_write *write, rhizome_manifest *m, enum rhizome_payload_status status);

View File

@ -17,6 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <fcntl.h>
#include "cli.h"
#include "conf.h"
#include "keyring.h"
@ -101,9 +102,59 @@ static int app_rhizome_hash_file(const struct cli_parsed *parsed, struct cli_con
return 0;
}
static int append_manifest_zip_comment(const char *filepath, rhizome_manifest *m)
{
int fd = open(filepath, O_RDWR);
if (fd==-1)
return WHYF_perror("open(%s,O_RDWR)", alloca_str_toprint(filepath));
int ret=0;
uint8_t EOCD[22];
if (lseek(fd, -(sizeof EOCD), SEEK_END)==-1){
ret = WHYF_perror("lseek(%d,%d,SEEK_END)", fd, -(sizeof EOCD));
goto end;
}
if (read(fd, EOCD, sizeof EOCD)==-1){
ret = WHYF_perror("read(%d,%p,%zu)", fd, EOCD, sizeof EOCD);
goto end;
}
if(EOCD[20] || EOCD[21]){
ret = WHYF("Expected 0x00 0x00 at end of file, found 0x%02x 0x%02x", EOCD[20], EOCD[21]);
goto end;
}
if(EOCD[0]!=0x50 || EOCD[1]!=0x4b || EOCD[2]!=0x05 || EOCD[3]!=0x06){
ret = WHYF("Expected zip EOCD marker 0x504b0506 near end of file");
goto end;
}
if (lseek(fd, -2, SEEK_END)==-1){
ret = WHYF_perror("lseek(%d,-2,SEEK_END)", fd);
goto end;
}
uint8_t len[2];
len[0]=m->manifest_all_bytes & 0xFF;
len[1]=(m->manifest_all_bytes >> 8)& 0xFF;
if (write(fd, len, sizeof len)==-1){
ret = WHYF_perror("write(%d,%p,2)", fd, len);
goto end;
}
if (write(fd, m->manifestdata, m->manifest_all_bytes)==-1){
ret = WHYF_perror("write(%d,%p,%d)", fd, m->manifestdata, m->manifest_all_bytes);
goto end;
}
end:
close(fd);
return ret;
}
DEFINE_CMD(app_rhizome_add_file, 0,
"Add a file to Rhizome and optionally write its manifest to the given path",
"rhizome","add","file" KEYRING_PIN_OPTIONS,"[--bundle=<bundleid>]","[--force-new]","<author_sid>","<filepath>","[<manifestpath>]","[<bsk>]","...");
"rhizome","add","file" KEYRING_PIN_OPTIONS,"[--zip-comment]","[--bundle=<bundleid>]","[--force-new]","<author_sid>","<filepath>","[<manifestpath>]","[<bsk>]","...");
DEFINE_CMD(app_rhizome_add_file, 0,
"Append content to a journal bundle",
"rhizome", "journal", "append" KEYRING_PIN_OPTIONS, "<author_sid>", "<bundleid>", "<filepath>", "[<bsk>]");
@ -121,6 +172,7 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
cli_arg(parsed, "bundleid", &bundleIdHex, cli_optional_bid, "");
if (cli_arg(parsed, "bsk", &bsktext, cli_optional_bundle_secret_key, NULL) == -1)
return -1;
int zip_comment = 0 == cli_arg(parsed, "--zip-comment", NULL, NULL, NULL);
sid_t authorSid;
if (!authorSidHex || !*authorSidHex)
@ -294,6 +346,10 @@ static int app_rhizome_add_file(const struct cli_parsed *parsed, struct cli_cont
case RHIZOME_BUNDLE_STATUS_OLD:
assert(mout != NULL);
cli_put_manifest(context, mout);
if (zip_comment)
append_manifest_zip_comment(filepath, mout);
if ( manifestpath && *manifestpath
&& rhizome_write_manifest_file(mout, manifestpath, 0) == -1
)
@ -329,20 +385,22 @@ finish:
DEFINE_CMD(app_rhizome_import_bundle, 0,
"Import a payload/manifest pair into Rhizome",
"rhizome","import","bundle","<filepath>","<manifestpath>");
"rhizome","import","bundle","[--zip-comment]","<filepath>","<manifestpath>");
static int app_rhizome_import_bundle(const struct cli_parsed *parsed, struct cli_context *context)
{
DEBUG_cli_parsed(verbose, parsed);
const char *filepath, *manifestpath;
cli_arg(parsed, "filepath", &filepath, NULL, "");
cli_arg(parsed, "manifestpath", &manifestpath, NULL, "");
int zip_comment = 0 == cli_arg(parsed, "--zip-comment", NULL, NULL, NULL);
if (rhizome_opendb() == -1)
return -1;
rhizome_manifest *m = rhizome_new_manifest();
if (!m)
return WHY("Out of manifests.");
rhizome_manifest *m_out = NULL;
enum rhizome_bundle_status status = rhizome_bundle_import_files(m, &m_out, manifestpath, filepath);
enum rhizome_bundle_status status = rhizome_bundle_import_files(m, &m_out, manifestpath, filepath, zip_comment);
switch (status) {
case RHIZOME_BUNDLE_STATUS_NEW:
cli_put_manifest(context, m);
@ -368,7 +426,7 @@ static int app_rhizome_import_bundle(const struct cli_parsed *parsed, struct cli
DEFINE_CMD(app_rhizome_append_manifest, 0,
"Append a manifest to the end of the file it belongs to.",
"rhizome", "append", "manifest", "<filepath>", "<manifestpath>");
"rhizome", "append", "manifest", "[--zip-comment]", "<filepath>", "<manifestpath>");
static int app_rhizome_append_manifest(const struct cli_parsed *parsed, struct cli_context *UNUSED(context))
{
DEBUG_cli_parsed(verbose, parsed);
@ -376,6 +434,8 @@ static int app_rhizome_append_manifest(const struct cli_parsed *parsed, struct c
if ( cli_arg(parsed, "manifestpath", &manifestpath, NULL, "") == -1
|| cli_arg(parsed, "filepath", &filepath, NULL, "") == -1)
return -1;
int zip_comment = 0 == cli_arg(parsed, "--zip-comment", NULL, NULL, NULL);
rhizome_manifest *m = rhizome_new_manifest();
if (!m)
return WHY("Out of manifests.");
@ -384,8 +444,12 @@ static int app_rhizome_append_manifest(const struct cli_parsed *parsed, struct c
&& rhizome_manifest_validate(m)
&& rhizome_manifest_verify(m)
) {
if (rhizome_write_manifest_file(m, filepath, 1) != -1)
ret = 0;
if (zip_comment){
append_manifest_zip_comment(filepath, m);
}else{
if (rhizome_write_manifest_file(m, filepath, 1) != -1)
ret = 0;
}
}
rhizome_manifest_free(m);
return ret;
@ -488,7 +552,7 @@ static int app_rhizome_clean(const struct cli_parsed *parsed, struct cli_context
DEFINE_CMD(app_rhizome_extract, 0,
"Export a manifest and payload file to the given paths, without decrypting.",
"rhizome","export","bundle" KEYRING_PIN_OPTIONS,
"<manifestid>","[<manifestpath>]","[<filepath>]");
"[--zip-comment]","<manifestid>","[<manifestpath>]","[<filepath>]");
DEFINE_CMD(app_rhizome_extract, 0,
"Export a manifest from Rhizome and write it to the given path",
"rhizome","export","manifest" KEYRING_PIN_OPTIONS,
@ -512,7 +576,8 @@ static int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_conte
return -1;
int extract = strcasecmp(parsed->args[1], "extract")==0;
int zip_comment = 0 == cli_arg(parsed, "--zip-comment", NULL, NULL, NULL);
/* Ensure the Rhizome database exists and is open */
if (create_serval_instance_dir() == -1)
return -1;
@ -577,13 +642,18 @@ static int app_rhizome_extract(const struct cli_parsed *parsed, struct cli_conte
}
}
if (ret==0 && zip_comment && pstatus == RHIZOME_PAYLOAD_STATUS_STORED){
if (append_manifest_zip_comment(filepath, m) == -1)
ret = -1;
}
if (ret==0 && manifestpath && *manifestpath){
if (strcmp(manifestpath, "-") == 0) {
// always extract a manifest to stdout, even if writing the file itself failed.
cli_field_name(context, "manifest", ":");
cli_write(context, m->manifestdata, m->manifest_all_bytes);
cli_delim(context, "\n");
} else {
} else if (!zip_comment) {
int append = (strcmp(manifestpath, filepath)==0)?1:0;
// don't write out the manifest if we were asked to append it and writing the file failed.
if (!append || (pstatus == RHIZOME_PAYLOAD_STATUS_EMPTY || pstatus == RHIZOME_PAYLOAD_STATUS_STORED)) {

View File

@ -127,7 +127,7 @@ static int rhizome_direct_import_end(struct http_request *hr)
return 0;
}
struct rhizome_bundle_result result = INVALID_RHIZOME_BUNDLE_RESULT;
result.status = rhizome_bundle_import_files(m, NULL, manifest_path, payload_path);
result.status = rhizome_bundle_import_files(m, NULL, manifest_path, payload_path, 0);
rhizome_manifest_free(m);
rhizome_direct_clear_temporary_files(r);
http_request_rhizome_bundle_status_response(r, result, NULL);

View File

@ -609,23 +609,29 @@ int rhizome_write_buffer(struct rhizome_write *write_state, uint8_t *buffer, siz
/* If file_length is known, then expects file to be at least file_length in size, ignoring anything
* longer than that. Returns 0 if successful, -1 if error (logged).
*/
int rhizome_write_file(struct rhizome_write *write, const char *filename)
int rhizome_write_file(struct rhizome_write *write, const char *filename, off_t offset, uint64_t length)
{
int fd = open(filename, O_RDONLY);
if (fd == -1)
return WHYF_perror("open(%s,O_RDONLY)", alloca_str_toprint(filename));
unsigned char buffer[RHIZOME_CRYPT_PAGE_SIZE];
int ret=0;
while (write->file_length == RHIZOME_SIZE_UNSET || write->file_offset < write->file_length) {
if (offset){
if (lseek(fd, offset, SEEK_SET)==-1)
return WHYF_perror("lseek(%d,%zu,SEEK_SET)", fd, (unsigned long long)offset);
}
if (length == RHIZOME_SIZE_UNSET || length > write->file_length)
length = write->file_length;
while (length == RHIZOME_SIZE_UNSET || write->file_offset < length) {
size_t size = sizeof buffer;
if (write->file_length != RHIZOME_SIZE_UNSET && write->file_offset + size > write->file_length)
size = write->file_length - write->file_offset;
if (length != RHIZOME_SIZE_UNSET && write->file_offset + size > length)
size = length - write->file_offset;
ssize_t r = read(fd, buffer, size);
if (r == -1) {
ret = WHYF_perror("read(%d,%p,%zu)", fd, buffer, size);
break;
}
if (write->file_length != RHIZOME_SIZE_UNSET && (size_t) r != size) {
if (length != RHIZOME_SIZE_UNSET && (size_t) r != size) {
ret = WHYF("file truncated - read(%d,%p,%zu) returned %zu", fd, buffer, size, (size_t) r);
break;
}
@ -847,7 +853,7 @@ enum rhizome_payload_status rhizome_import_payload_from_file(rhizome_manifest *m
return status;
// file payload is not in the store yet
if (rhizome_write_file(&write, filepath)){
if (rhizome_write_file(&write, filepath, 0, RHIZOME_SIZE_UNSET)){
rhizome_fail_write(&write);
return RHIZOME_PAYLOAD_STATUS_ERROR;
}
@ -971,7 +977,7 @@ enum rhizome_payload_status rhizome_store_payload_file(rhizome_manifest *m, cons
}
if (!status_ok)
FATALF("rhizome_write_open_manifest() returned status = %d", status);
if (rhizome_write_file(&write, filepath) == -1)
if (rhizome_write_file(&write, filepath, 0, RHIZOME_SIZE_UNSET) == -1)
status = RHIZOME_PAYLOAD_STATUS_ERROR;
else
status = rhizome_finish_write(&write);
@ -1382,7 +1388,7 @@ static int write_file(struct rhizome_read *read, const char *filepath){
while((ret=rhizome_read(read, buffer, sizeof(buffer)))>0){
if (fd!=-1){
if (write(fd,buffer,ret)!=ret) {
ret = WHY("Failed to write data to file");
ret = WHY_perror("Failed to write data to file");
break;
}
}
@ -1677,7 +1683,7 @@ enum rhizome_payload_status rhizome_append_journal_file(rhizome_manifest *m, uin
enum rhizome_payload_status status = rhizome_write_open_journal(&write, m, advance_by, stat.st_size);
if (status != RHIZOME_PAYLOAD_STATUS_NEW)
return status;
if (stat.st_size != 0 && rhizome_write_file(&write, filename) == -1)
if (stat.st_size != 0 && rhizome_write_file(&write, filename, 0, RHIZOME_SIZE_UNSET) == -1)
status = RHIZOME_PAYLOAD_STATUS_ERROR;
else
status = rhizome_finish_write(&write);

View File

@ -1431,6 +1431,34 @@ test_ImportCombinedBundle() {
assert diff fileA fileAx
}
doc_ImportCombinedZipBundle="Create and import combined zip bundle"
setup_ImportCombinedZipBundle() {
# A "combined bundle" is a single file consisting of a payload with its
# manifest appended to the end.
setup_servald
setup_rhizome
echo "Hello from A" >fileA
zip fileA.zip fileA
}
test_ImportCombinedZipBundle() {
# Create the combined bundle
executeOk_servald rhizome add file --zip-comment $SIDA fileA.zip fileA.manifest
extract_manifest_id manifestid fileA.manifest
extract_manifest_filehash filehash fileA.manifest
extract_manifest_filesize filesize fileA.manifest
# Import the combined bundle
set_instance +B
executeOk_servald rhizome import bundle --zip-comment fileA.zip fileA.zip
assertStdoutGrep --matches=1 "^service:file$"
assertStdoutGrep --matches=1 "^manifestid:$manifestid\$"
assertStdoutGrep --matches=1 "^filehash:$filehash\$"
assertStdoutGrep --matches=1 "^filesize:$filesize\$"
executeOk_servald rhizome list
assert_rhizome_list --fromhere=0 fileA.zip
executeOk_servald rhizome export bundle --zip-comment $manifestid fileAx.zip fileAx.zip
assert diff fileA.zip fileAx.zip
}
doc_ImportJournal="Import a journal bundle"
setup_ImportJournal() {
B_IDENTITY_COUNT=1