Added command ipfs object get [hash]
This will display the formatted data of a MerkleDag (links and data)
This commit is contained in:
parent
7fa0fc6a7b
commit
da4b1f86f4
6 changed files with 132 additions and 27 deletions
|
@ -70,3 +70,71 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get a file by its hash, and write the data to a file
|
||||||
|
* @param hash the base58 multihash of the cid
|
||||||
|
* @param file_name the file name to write to
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_repo) {
|
||||||
|
// convert hash to cid
|
||||||
|
struct Cid* cid = NULL;
|
||||||
|
if ( ipfs_cid_decode_hash_from_base58(hash, strlen((char*)hash), &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);
|
||||||
|
|
||||||
|
// process blocks
|
||||||
|
struct NodeLink* link = read_node->head_link;
|
||||||
|
printf("Links:[");
|
||||||
|
while (link != NULL) {
|
||||||
|
unsigned char b58[100];
|
||||||
|
ipfs_cid_hash_to_base58(link->hash, link->hash_size, b58, 100);
|
||||||
|
printf("{\"Name\":\"%s\",\"Hash\":\"%s\",\"Size\":%lu}", (link->name != NULL ? link->name : ""), (char*)b58, link->t_size);
|
||||||
|
link = link->next;
|
||||||
|
}
|
||||||
|
printf("],\"Data\":\"");
|
||||||
|
for(size_t i = 0LU; i < read_node->data_size; i++) {
|
||||||
|
printf("%02x", read_node->data[i]);
|
||||||
|
}
|
||||||
|
printf("\"}\n");
|
||||||
|
|
||||||
|
if (read_node != NULL)
|
||||||
|
ipfs_node_free(read_node);
|
||||||
|
|
||||||
|
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
|
||||||
|
* @param argv arguments
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int ipfs_exporter_object_get(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
|
||||||
|
retVal = ipfs_exporter_to_console((unsigned char*)argv[3], fs_repo);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "ipfs/importer/importer.h"
|
#include "ipfs/importer/importer.h"
|
||||||
#include "ipfs/merkledag/merkledag.h"
|
#include "ipfs/merkledag/merkledag.h"
|
||||||
#include "ipfs/repo/fsrepo/fs_repo.h"
|
#include "ipfs/repo/fsrepo/fs_repo.h"
|
||||||
|
#include "ipfs/unixfs/unixfs.h"
|
||||||
|
|
||||||
#define MAX_DATA_SIZE 262144 // 1024 * 256;
|
#define MAX_DATA_SIZE 262144 // 1024 * 256;
|
||||||
|
|
||||||
|
@ -16,27 +19,48 @@
|
||||||
* @param node the node to add to
|
* @param node the node to add to
|
||||||
* @returns number of bytes read
|
* @returns number of bytes read
|
||||||
*/
|
*/
|
||||||
size_t ipfs_import_chunk(FILE* file, struct Node* node, struct FSRepo* fs_repo) {
|
size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs_repo, size_t* total_size) {
|
||||||
unsigned char buffer[MAX_DATA_SIZE];
|
unsigned char buffer[MAX_DATA_SIZE];
|
||||||
size_t bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file);
|
size_t bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file);
|
||||||
|
|
||||||
if (node->data_size == 0) {
|
// create a new node
|
||||||
ipfs_node_set_data(node, buffer, bytes_read);
|
struct Node* new_node = NULL;
|
||||||
} else {
|
ipfs_node_new_from_data(buffer, bytes_read, &new_node);
|
||||||
// create a new node, and link to the parent
|
// persist
|
||||||
struct Node* new_node = NULL;
|
ipfs_merkledag_add(new_node, fs_repo);
|
||||||
ipfs_node_new_from_data(buffer, bytes_read, &new_node);
|
// put link in parent node
|
||||||
// persist
|
struct NodeLink* new_link = NULL;
|
||||||
ipfs_merkledag_add(new_node, fs_repo);
|
ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link);
|
||||||
// put link in parent node
|
new_link->t_size = new_node->data_size;
|
||||||
struct NodeLink* new_link = NULL;
|
*total_size += new_link->t_size;
|
||||||
ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link);
|
ipfs_node_add_link(parent_node, new_link);
|
||||||
ipfs_node_add_link(node, new_link);
|
ipfs_node_free(new_node);
|
||||||
ipfs_node_free(new_node);
|
// save the parent_node if it is time...
|
||||||
}
|
|
||||||
if (bytes_read != MAX_DATA_SIZE) {
|
if (bytes_read != MAX_DATA_SIZE) {
|
||||||
|
// build UnixFS for file
|
||||||
|
struct UnixFS* unix_fs;
|
||||||
|
if (ipfs_unixfs_new(&unix_fs) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
unix_fs->data_type = UNIXFS_FILE;
|
||||||
|
unix_fs->file_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);
|
||||||
|
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);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(parent_node->data, temp, bytes_written);
|
||||||
// persist the main node
|
// persist the main node
|
||||||
ipfs_merkledag_add(node, fs_repo);
|
ipfs_merkledag_add(parent_node, fs_repo);
|
||||||
}
|
}
|
||||||
return bytes_read;
|
return bytes_read;
|
||||||
}
|
}
|
||||||
|
@ -44,21 +68,22 @@ size_t ipfs_import_chunk(FILE* file, struct Node* node, struct FSRepo* fs_repo)
|
||||||
/**
|
/**
|
||||||
* Creates a node based on an incoming file
|
* Creates a node based on an incoming file
|
||||||
* @param file_name the file to import
|
* @param file_name the file to import
|
||||||
* @param node the root node (could have links to others)
|
* @param parent_node the root node (has links to others)
|
||||||
* @returns true(1) on success
|
* @returns true(1) on success
|
||||||
*/
|
*/
|
||||||
int ipfs_import_file(const char* fileName, struct Node** node, struct FSRepo* fs_repo) {
|
int ipfs_import_file(const char* fileName, struct Node** parent_node, struct FSRepo* fs_repo) {
|
||||||
int retVal = 1;
|
int retVal = 1;
|
||||||
int bytes_read = MAX_DATA_SIZE;
|
int bytes_read = MAX_DATA_SIZE;
|
||||||
|
size_t total_size = 0;
|
||||||
|
|
||||||
FILE* file = fopen(fileName, "rb");
|
FILE* file = fopen(fileName, "rb");
|
||||||
retVal = ipfs_node_new(node);
|
retVal = ipfs_node_new(parent_node);
|
||||||
if (retVal == 0)
|
if (retVal == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// add all nodes
|
// add all nodes
|
||||||
while ( bytes_read == MAX_DATA_SIZE) {
|
while ( bytes_read == MAX_DATA_SIZE) {
|
||||||
bytes_read = ipfs_import_chunk(file, *node, fs_repo);
|
bytes_read = ipfs_import_chunk(file, *parent_node, fs_repo, &total_size);
|
||||||
}
|
}
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
@ -76,7 +101,7 @@ int ipfs_import(int argc, char** argv) {
|
||||||
* param 1: add
|
* param 1: add
|
||||||
* param 2: filename
|
* param 2: filename
|
||||||
*/
|
*/
|
||||||
struct Node* node = NULL;
|
struct Node* directory_node = NULL;
|
||||||
struct FSRepo* fs_repo = NULL;
|
struct FSRepo* fs_repo = NULL;
|
||||||
|
|
||||||
// open the repo
|
// open the repo
|
||||||
|
@ -87,20 +112,20 @@ int ipfs_import(int argc, char** argv) {
|
||||||
retVal = ipfs_repo_fsrepo_open(fs_repo);
|
retVal = ipfs_repo_fsrepo_open(fs_repo);
|
||||||
|
|
||||||
// import the file(s)
|
// import the file(s)
|
||||||
retVal = ipfs_import_file(argv[2], &node, fs_repo);
|
retVal = ipfs_import_file(argv[2], &directory_node, fs_repo);
|
||||||
|
|
||||||
// give some results to the user
|
// give some results to the user
|
||||||
int buffer_len = 100;
|
int buffer_len = 100;
|
||||||
unsigned char buffer[buffer_len];
|
unsigned char buffer[buffer_len];
|
||||||
retVal = ipfs_cid_hash_to_base58(node->hash, node->hash_size, buffer, buffer_len);
|
retVal = ipfs_cid_hash_to_base58(directory_node->hash, directory_node->hash_size, buffer, buffer_len);
|
||||||
if (retVal == 0) {
|
if (retVal == 0) {
|
||||||
printf("Unable to generate hash\n");
|
printf("Unable to generate hash\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf("added %s %s\n", buffer, argv[2]);
|
printf("added %s %s\n", buffer, argv[2]);
|
||||||
|
|
||||||
if (node != NULL)
|
if (directory_node != NULL)
|
||||||
ipfs_node_free(node);
|
ipfs_node_free(directory_node);
|
||||||
if (fs_repo != NULL)
|
if (fs_repo != NULL)
|
||||||
ipfs_repo_fsrepo_free(fs_repo);
|
ipfs_repo_fsrepo_free(fs_repo);
|
||||||
|
|
||||||
|
|
|
@ -7,3 +7,6 @@
|
||||||
* @returns true(1) on success
|
* @returns true(1) on success
|
||||||
*/
|
*/
|
||||||
int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, const struct FSRepo* fs_repo);
|
int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, const struct FSRepo* fs_repo);
|
||||||
|
|
||||||
|
int ipfs_exporter_object_get(int argc, char** argv);
|
||||||
|
|
||||||
|
|
BIN
main/ipfs
BIN
main/ipfs
Binary file not shown.
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "ipfs/repo/init.h"
|
#include "ipfs/repo/init.h"
|
||||||
#include "ipfs/importer/importer.h"
|
#include "ipfs/importer/importer.h"
|
||||||
|
#include "ipfs/importer/exporter.h"
|
||||||
|
|
||||||
void stripit(int argc, char** argv) {
|
void stripit(int argc, char** argv) {
|
||||||
char tmp[strlen(argv[argc])];
|
char tmp[strlen(argv[argc])];
|
||||||
|
@ -22,6 +23,7 @@ void strip_quotes(int argc, char** argv) {
|
||||||
|
|
||||||
#define INIT 1
|
#define INIT 1
|
||||||
#define ADD 2
|
#define ADD 2
|
||||||
|
#define OBJECT_GET 3
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Basic parsing of command line arguments to figure out where the user wants to go
|
* Basic parsing of command line arguments to figure out where the user wants to go
|
||||||
|
@ -37,6 +39,9 @@ int parse_arguments(int argc, char** argv) {
|
||||||
if (strcmp("add", argv[1]) == 0) {
|
if (strcmp("add", argv[1]) == 0) {
|
||||||
return ADD;
|
return ADD;
|
||||||
}
|
}
|
||||||
|
if (strcmp("object", argv[1]) == 0 && argc > 2 && strcmp("get", argv[2]) == 0) {
|
||||||
|
return OBJECT_GET;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,5 +58,8 @@ int main(int argc, char** argv) {
|
||||||
case (ADD):
|
case (ADD):
|
||||||
ipfs_import(argc, argv);
|
ipfs_import(argc, argv);
|
||||||
break;
|
break;
|
||||||
|
case (OBJECT_GET):
|
||||||
|
ipfs_exporter_object_get(argc, argv);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,8 +42,9 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Retrieves a node from the datastore based on the cid
|
* Retrieves a node from the datastore based on the hash
|
||||||
* @param cid the key to look for
|
* @param hash the key to look for
|
||||||
|
* @param hash_size the length of the key
|
||||||
* @param node the node to be created
|
* @param node the node to be created
|
||||||
* @param fs_repo the repository
|
* @param fs_repo the repository
|
||||||
* @returns true(1) on success
|
* @returns true(1) on success
|
||||||
|
|
Loading…
Reference in a new issue