diff --git a/importer/exporter.c b/importer/exporter.c index a8e8941..00fc683 100644 --- a/importer/exporter.c +++ b/importer/exporter.c @@ -115,7 +115,6 @@ int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_ return 1; } - /*** * Called from the command line with ipfs object get [hash]. Retrieves the object pointed to by hash, and displays its block data (links and data elements) * @param argc number of arguments @@ -138,3 +137,65 @@ int ipfs_exporter_object_get(int argc, char** argv) { retVal = ipfs_exporter_to_console((unsigned char*)argv[3], fs_repo); return retVal; } + +int ipfs_exporter_cat_node(struct Node* node, const struct FSRepo* fs_repo) { + // process this block, then move on to the links + for(size_t i = 0LU; i < node->data_size; i++) { + printf("%c", node->data[i]); + } + // process links + struct NodeLink* current = node->head_link; + while (current != NULL) { + // find the node + struct Node* child_node = NULL; + if (ipfs_merkledag_get(current->hash, current->hash_size, &child_node, fs_repo) == 0) { + return 0; + } + ipfs_exporter_cat_node(child_node, fs_repo); + ipfs_node_free(child_node); + current = current->next; + } + + return 1; +} + +/*** + * Called from the command line with ipfs cat [hash]. Retrieves the object pointed to by hash, and displays its block data (links and data elements) + * @param argc number of arguments + * @param argv arguments + * @returns true(1) on success + */ +int ipfs_exporter_object_cat(int argc, char** argv) { + struct FSRepo* fs_repo = NULL; + + // open the repo + int retVal = ipfs_repo_fsrepo_new(NULL, NULL, &fs_repo); + if (retVal == 0) { + return 0; + } + retVal = ipfs_repo_fsrepo_open(fs_repo); + if (retVal == 0) { + return 0; + } + // find hash + // convert hash to cid + struct Cid* cid = NULL; + if ( ipfs_cid_decode_hash_from_base58((unsigned char*)argv[2], strlen(argv[2]), &cid) == 0) { + return 0; + } + + // find block + struct Node* read_node = NULL; + if (ipfs_merkledag_get(cid->hash, cid->hash_length, &read_node, fs_repo) == 0) { + ipfs_cid_free(cid); + return 0; + } + // no longer need the cid + ipfs_cid_free(cid); + + ipfs_exporter_cat_node(read_node, fs_repo); + ipfs_node_free(read_node); + + return retVal; + +} diff --git a/importer/importer.c b/importer/importer.c index e1564d9..04cc936 100644 --- a/importer/importer.c +++ b/importer/importer.c @@ -48,66 +48,71 @@ size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs ipfs_unixfs_free(new_unixfs); return 0; } - // create a new node - if (ipfs_node_new_from_data(protobuf, bytes_written, &new_node) == 0) { - return 0; - } - if (ipfs_node_set_hash(new_node, new_unixfs->hash, new_unixfs->hash_length) == 0) { - ipfs_node_free(new_node); - return 0; - } // we're done with the UnixFS object ipfs_unixfs_free(new_unixfs); - // persist - size_t size_of_node = 0; - if (ipfs_merkledag_add(new_node, fs_repo, &size_of_node) == 0) { - ipfs_node_free(new_node); - return 0; - } - // put link in parent node - if (ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link) == 0) { - ipfs_node_free(new_node); - return 0; - } - new_link->t_size = size_of_node; - *total_size += new_link->t_size; - // NOTE: disposal of this link object happens when the parent is disposed - if (ipfs_node_add_link(parent_node, new_link) == 0) { - ipfs_node_free(new_node); - return 0; - } - ipfs_node_free(new_node); - if (bytes_read != MAX_DATA_SIZE) { - // We have read everything, now save the parent_node, - // which is a sort of "directory" entry - /* - // build UnixFS for the parent - struct UnixFS* unix_fs; - if (ipfs_unixfs_new(&unix_fs) == 0) { + + // if there is more to read, create a new node. + if (bytes_read == MAX_DATA_SIZE) { + // create a new node + if (ipfs_node_new_from_data(protobuf, bytes_written, &new_node) == 0) { return 0; } - unix_fs->data_type = UNIXFS_FILE; - unix_fs->bytes_size = *total_size; - // now encode unixfs and put in parent_node->data - size_t temp_size = ipfs_unixfs_protobuf_encode_size(unix_fs); - unsigned char temp[temp_size]; - size_t bytes_written; - if (ipfs_unixfs_protobuf_encode(unix_fs, temp, temp_size, &bytes_written) == 0) { - ipfs_unixfs_free(unix_fs); + // persist + size_t size_of_node = 0; + if (ipfs_merkledag_add(new_node, fs_repo, &size_of_node) == 0) { + ipfs_node_free(new_node); return 0; } - parent_node->data_size = bytes_written; - parent_node->data = (unsigned char*)malloc(bytes_written); - if (parent_node->data == NULL) { - ipfs_unixfs_free(unix_fs); + + // put link in parent node + if (ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link) == 0) { + ipfs_node_free(new_node); return 0; } - memcpy(parent_node->data, temp, bytes_written); - ipfs_unixfs_free(unix_fs); - */ + new_link->t_size = size_of_node; + *total_size += new_link->t_size; + // NOTE: disposal of this link object happens when the parent is disposed + if (ipfs_node_add_link(parent_node, new_link) == 0) { + ipfs_node_free(new_node); + return 0; + } + ipfs_node_free(new_node); + } else { + // if there are no existing links, put what we pulled from the file into parent_node + // otherwise, add it as a link + if (parent_node->head_link == NULL) { + ipfs_node_set_data(parent_node, protobuf, bytes_written); + } else { + // there are existing links. put the data in a new node, save it, then put the link in parent_node + // create a new node + if (ipfs_node_new_from_data(protobuf, bytes_written, &new_node) == 0) { + return 0; + } + // persist + size_t size_of_node = 0; + if (ipfs_merkledag_add(new_node, fs_repo, &size_of_node) == 0) { + ipfs_node_free(new_node); + return 0; + } + + // put link in parent node + if (ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link) == 0) { + ipfs_node_free(new_node); + return 0; + } + new_link->t_size = size_of_node; + *total_size += new_link->t_size; + // NOTE: disposal of this link object happens when the parent is disposed + if (ipfs_node_add_link(parent_node, new_link) == 0) { + ipfs_node_free(new_node); + return 0; + } + ipfs_node_free(new_node); + } // persist the main node ipfs_merkledag_add(parent_node, fs_repo, &bytes_written); - } + } // add to parent vs add as link + return bytes_read; } @@ -131,6 +136,7 @@ int ipfs_import_file(const char* fileName, struct Node** parent_node, struct FSR while ( bytes_read == MAX_DATA_SIZE) { bytes_read = ipfs_import_chunk(file, *parent_node, fs_repo, &total_size); } + fclose(file); return 1; diff --git a/include/ipfs/importer/exporter.h b/include/ipfs/importer/exporter.h index 395199c..da3f650 100644 --- a/include/ipfs/importer/exporter.h +++ b/include/ipfs/importer/exporter.h @@ -10,3 +10,10 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons int ipfs_exporter_object_get(int argc, char** argv); +/*** + * Called from the command line with ipfs cat [hash]. Retrieves the object pointed to by hash, and displays its block data (links and data elements) + * @param argc number of arguments + * @param argv arguments + * @returns true(1) on success + */ +int ipfs_exporter_object_cat(int argc, char** argv); diff --git a/main/main.c b/main/main.c index d8b9136..6b969f3 100644 --- a/main/main.c +++ b/main/main.c @@ -26,6 +26,7 @@ void strip_quotes(int argc, char** argv) { #define ADD 2 #define OBJECT_GET 3 #define DNS 4 +#define CAT 5 /*** * Basic parsing of command line arguments to figure out where the user wants to go @@ -44,6 +45,9 @@ int parse_arguments(int argc, char** argv) { if (strcmp("object", argv[1]) == 0 && argc > 2 && strcmp("get", argv[2]) == 0) { return OBJECT_GET; } + if (strcmp("cat", argv[1]) == 0) { + return CAT; + } if (strcmp("dns", argv[1]) == 0) { return DNS; } @@ -66,6 +70,9 @@ int main(int argc, char** argv) { case (OBJECT_GET): ipfs_exporter_object_get(argc, argv); break; + case (CAT): + ipfs_exporter_object_cat(argc, argv); + break; case (DNS): ipfs_dns(argc, argv); break; diff --git a/repo/fsrepo/lmdb_datastore.c b/repo/fsrepo/lmdb_datastore.c index 6af119e..1bcd5a9 100644 --- a/repo/fsrepo/lmdb_datastore.c +++ b/repo/fsrepo/lmdb_datastore.c @@ -106,9 +106,6 @@ int repo_fsrepo_lmdb_put(unsigned const char* key, size_t key_size, unsigned cha db_key.mv_size = key_size; db_key.mv_data = (char*)key; - // JMJ debugging - //printf("Saving key of %lu bytes that starts with %02x and ends with %02x\n", db_key.mv_size, ((char*)db_key.mv_data)[0], ((char*)db_key.mv_data)[db_key.mv_size-1]); - // write db_value.mv_size = data_size; db_value.mv_data = data;