diff --git a/.cproject b/.cproject
index c73ace8..9bbebce 100644
--- a/.cproject
+++ b/.cproject
@@ -14,7 +14,7 @@
-
+
@@ -58,40 +58,6 @@
-
-
-
- make
- all
- true
- true
- true
-
-
- make
- clean
- true
- true
- true
-
-
- make
-
- clean
- true
- false
- true
-
-
- make
-
- clean
- true
- false
- true
-
-
-
@@ -101,4 +67,46 @@
+
+
+
+ make
+
+ all
+ true
+ true
+ true
+
+
+ make
+
+ clean
+ true
+ true
+ true
+
+
+ make
+
+ rebuild
+ true
+ true
+ true
+
+
+ make
+ clean
+ true
+ false
+ true
+
+
+ make
+ clean
+ true
+ false
+ true
+
+
+
diff --git a/Makefile b/Makefile
index 778029a..fc6bf07 100644
--- a/Makefile
+++ b/Makefile
@@ -3,6 +3,7 @@ DEBUG = true
export DEBUG
all:
+ cd blocks; make all;
cd cid; make all;
cd cmd; make all;
cd commands; make all;
@@ -16,6 +17,7 @@ all:
cd test; make all;
clean:
+ cd blocks; make clean;
cd cid; make clean;
cd cmd; make clean;
cd commands; make clean;
@@ -27,4 +29,5 @@ clean:
cd datastore; make clean;
cd thirdparty; make clean;
cd test; make clean;
-
+
+rebuild: clean all
diff --git a/blocks/Makefile b/blocks/Makefile
new file mode 100644
index 0000000..9828cc1
--- /dev/null
+++ b/blocks/Makefile
@@ -0,0 +1,18 @@
+CC = gcc
+CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include
+
+ifdef DEBUG
+CFLAGS += -g3
+endif
+
+LFLAGS =
+DEPS = ../include/blocks/block.h ../include/blocks/blockstore.h
+OBJS = block.o blockstore.o
+
+%.o: %.c $(DEPS)
+ $(CC) -c -o $@ $< $(CFLAGS)
+
+all: $(OBJS)
+
+clean:
+ rm -f *.o
diff --git a/blocks/block.c b/blocks/block.c
index 6359442..4d6dcf6 100644
--- a/blocks/block.c
+++ b/blocks/block.c
@@ -3,6 +3,7 @@
*/
#include
+#include
#include "libp2p/crypto/sha256.h"
#include "ipfs/blocks/block.h"
@@ -15,7 +16,7 @@
* @param block a pointer to the struct Block that will be created
* @returns true(1) on success
*/
-int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block** block) {
+int ipfs_blocks_block_new(const unsigned char* data, size_t data_size, struct Block** block) {
// allocate memory for structure
(*block) = (struct Block*)malloc(sizeof(struct Block));
@@ -23,25 +24,27 @@ int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block**
return 0;
// cid
- char hash[32];
- if (libp2p_crypto_hashing_sha256(data, hash, 32) == 0) {
+ unsigned char hash[32];
+ if (libp2p_crypto_hashing_sha256(data, data_size, &hash[0]) == 0) {
free(*block);
return 0;
}
- if (ipfs_cid_new(0, hash, 32, CID_PROTOBUF, (*block)->cid) == 0) {
+ if (ipfs_cid_new(0, hash, 32, CID_PROTOBUF, &((*block)->cid)) == 0) {
free(*block);
return 0;
}
- block->data = malloc(sizeof(unsigned char) * data_size);
- if (block->data == NULL) {
- ipfs_ci_free((*block)->cid);
+ (*block)->data_length = data_size;
+
+ (*block)->data = malloc(sizeof(unsigned char) * data_size);
+ if ( (*block)->data == NULL) {
+ ipfs_cid_free((*block)->cid);
free(*block);
return 0;
}
- memcpy(block->data, data, data_size);
+ memcpy( (*block)->data, data, data_size);
return 1;
}
diff --git a/blocks/blockstore.c b/blocks/blockstore.c
index bd86ae0..68d2803 100644
--- a/blocks/blockstore.c
+++ b/blocks/blockstore.c
@@ -1,14 +1,18 @@
/***
* a thin wrapper over a datastore for getting and putting block objects
*/
-
+#include "libp2p/crypto/encoding/base32.h"
+#include "ipfs/cid/cid.h"
+#include "ipfs/blocks/block.h"
+#include "ipfs/datastore/ds_helper.h"
+#include "ipfs/repo/fsrepo/fs_repo.h"
/**
* Delete a block based on its Cid
* @param cid the Cid to look for
* @param returns true(1) on success
*/
-int ipfs_blockstore_delete(struct Cid* cid) {
+int ipfs_blockstore_delete(struct Cid* cid, struct FSRepo* fs_repo) {
return 0;
}
@@ -17,7 +21,7 @@ int ipfs_blockstore_delete(struct Cid* cid) {
* @param cid the Cid to look for
* @returns true(1) if found
*/
-int ipfs_blockstore_has(struct Cid* cid) {
+int ipfs_blockstore_has(struct Cid* cid, struct FSRepo* fs_repo) {
return 0;
}
@@ -27,7 +31,7 @@ int ipfs_blockstore_has(struct Cid* cid) {
* @param block where to put the data to be returned
* @returns true(1) on success
*/
-int ipfs_blockstore_get(struct Cid* cid, struct Block* block) {
+int ipfs_blockstore_get(struct Cid* cid, struct Block* block, struct FSRepo* fs_repo) {
return 0;
}
@@ -36,9 +40,16 @@ int ipfs_blockstore_get(struct Cid* cid, struct Block* block) {
* @param block the block to store
* @returns true(1) on success
*/
-int ipfs_blockstore_put(struct Block* block) {
+int ipfs_blockstore_put(struct Block* block, struct FSRepo* fs_repo) {
// from blockstore.go line 118
- // TODO: Get Datastore key
- // TODO: send to Put with key
+ // Get Datastore key, which is a base32 key of the binary,
+ size_t key_length = libp2p_crypto_encoding_base32_encode_size(block->data_length);
+ unsigned char key[key_length];
+ int retVal = ipfs_datastore_helper_ds_key_from_binary(block->data, block->data_length, &key[0], key_length, &key_length);
+ if (retVal == 0)
+ return 0;
+
+ // send to Put with key
+ fs_repo->config->datastore->datastore_put(key, block, fs_repo->config->datastore);
return 0;
}
diff --git a/cmd/ipfs/init.c b/cmd/ipfs/init.c
index 468ec5f..2bd3a18 100644
--- a/cmd/ipfs/init.c
+++ b/cmd/ipfs/init.c
@@ -61,7 +61,7 @@ int do_init(FILE* out_file, char* repo_root, int empty, int num_bits_for_keypair
return 0;
//TODO: If the conf is null, make one
if ( conf->identity->peer_id == NULL) {
- int retVal = repo_config_init(conf, num_bits_for_keypair, repo_root);
+ int retVal = ipfs_repo_config_init(conf, num_bits_for_keypair, repo_root);
if (retVal == 0)
return 0;
}
@@ -87,11 +87,12 @@ int init_run(struct Request* request) {
// TODO: make sure offline
// TODO: check parameters for logic errors
// TODO: Initialize
- struct RepoConfig conf = {0};
+ struct RepoConfig* conf;
+ int retVal = ipfs_repo_config_new(&conf);
// TODO: handle files in request
// do the heavy lifting
int num_bits_for_key_pair = request->cmd.options[0]->default_int_val;
- return do_init(stdout, request->invoc_context->config_root, 1, num_bits_for_key_pair, &conf);
+ return do_init(stdout, request->invoc_context->config_root, 1, num_bits_for_key_pair, conf);
}
/***
diff --git a/datastore/Makefile b/datastore/Makefile
index e8bfbec..ec69298 100644
--- a/datastore/Makefile
+++ b/datastore/Makefile
@@ -1,5 +1,5 @@
CC = gcc
-CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include
+CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multihash/include -I../../c-multiaddr/include -I../../lmdb/libraries/liblmdb
ifdef DEBUG
CFLAGS += -g3
@@ -7,7 +7,7 @@ endif
LFLAGS =
DEPS = ../include/ipfsdatastore/ds_helper.h
-OBJS = ds_helper.o
+OBJS = ds_helper.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
diff --git a/datastore/key.c b/datastore/key.c
new file mode 100644
index 0000000..7baeb5a
--- /dev/null
+++ b/datastore/key.c
@@ -0,0 +1,18 @@
+#include
+
+/**
+ * Constructs a new "clean" key. Will remove things like slashes
+ * @param input the input
+ * @param output the output
+ * @param max_output_length the amount of memory allocated for output
+ * @param actual_output_length the amount of bytes written to output
+ * @returns true(1) on success
+ */
+int ipfs_datastore_key_new(const char* input, char* output, size_t max_output_length, size_t* actual_output_length) {
+ //TODO: clean the input
+ if (strlen(input) + 1 > max_output_length)
+ return 0;
+
+ memcpy(output, input, strlen(input) + 1);
+ return 1;
+}
diff --git a/include/ipfs/blocks/block.h b/include/ipfs/blocks/block.h
index f51f6c4..288c3f0 100644
--- a/include/ipfs/blocks/block.h
+++ b/include/ipfs/blocks/block.h
@@ -5,9 +5,12 @@
#ifndef __IPFS_BLOCKS_BLOCK_H__
#define __IPFS_BLOCKS_BLOCK_H__
+#include "ipfs/cid/cid.h"
+
struct Block {
struct Cid* cid;
unsigned char* data;
+ size_t data_length;
};
/***
@@ -17,7 +20,7 @@ struct Block {
* @param block a pointer to the struct Block that will be created
* @returns true(1) on success
*/
-int ipfs_blocks_block_new(unsigned char* data, size_t data_size, struct Block** block);
+int ipfs_blocks_block_new(const unsigned char* data, size_t data_size, struct Block** block);
/***
* Free resources used by the creation of a block
diff --git a/include/ipfs/blocks/blockstore.h b/include/ipfs/blocks/blockstore.h
index a4e10d6..f102c28 100644
--- a/include/ipfs/blocks/blockstore.h
+++ b/include/ipfs/blocks/blockstore.h
@@ -10,14 +10,14 @@
* @param cid the Cid to look for
* @param returns true(1) on success
*/
-int ipfs_blockstore_delete(struct Cid* cid);
+int ipfs_blockstore_delete(struct Cid* cid, struct FSRepo* fs_repo);
/***
* Determine if the Cid can be found
* @param cid the Cid to look for
* @returns true(1) if found
*/
-int ipfs_blockstore_has(struct Cid* cid);
+int ipfs_blockstore_has(struct Cid* cid, struct FSRepo* fs_repo);
/***
* Find a block based on its Cid
@@ -25,14 +25,14 @@ int ipfs_blockstore_has(struct Cid* cid);
* @param block where to put the data to be returned
* @returns true(1) on success
*/
-int ipfs_blockstore_get(struct Cid* cid, struct Block* block);
+int ipfs_blockstore_get(struct Cid* cid, struct Block* block, struct FSRepo* fs_repo);
/***
* Put a block in the blockstore
* @param block the block to store
* @returns true(1) on success
*/
-int ipfs_blockstore_put(struct Block* block);
+int ipfs_blockstore_put(struct Block* block, struct FSRepo* fs_repo);
#endif
diff --git a/include/ipfs/cid/cid.h b/include/ipfs/cid/cid.h
index 1f1b168..e499c41 100644
--- a/include/ipfs/cid/cid.h
+++ b/include/ipfs/cid/cid.h
@@ -5,6 +5,8 @@
#ifndef __IPFS_CID_CID_H
#define __IPFS_CID_CID_H
+#include
+
#define CID_PROTOBUF 0x70
#define CID_CBOR 0x71
#define CID_RAW 0x72
diff --git a/include/ipfs/datastore/key.h b/include/ipfs/datastore/key.h
new file mode 100644
index 0000000..626627a
--- /dev/null
+++ b/include/ipfs/datastore/key.h
@@ -0,0 +1,14 @@
+#ifndef __IPFS_DATASTORE_KEY_H__
+#define __IPFS_DATASTORE_KEY_H__
+
+/**
+ * Constructs a new "clean" key. Will remove things like slashes
+ * @param input the input
+ * @param output the output
+ * @param max_output_length the amount of memory allocated for output
+ * @param actual_output_length the amount of bytes written to output
+ * @returns true(1) on success
+ */
+int ipfs_datastore_key_new(const char* input, char* output, size_t max_output_length, size_t* actual_output_length);
+
+#endif
diff --git a/include/ipfs/repo/config/config.h b/include/ipfs/repo/config/config.h
index c8c978b..fc88071 100644
--- a/include/ipfs/repo/config/config.h
+++ b/include/ipfs/repo/config/config.h
@@ -72,7 +72,7 @@ int config_path(char* config_root, char* extension, char* result, int max_len);
* @param num_bits_for_keypair number of bits for the key pair
* @returns true(1) on success, otherwise 0
*/
-int repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_keypair, char* repo_path);
+int ipfs_repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_keypair, char* repo_path);
/***
* Initialize memory for a RepoConfig struct
diff --git a/include/ipfs/repo/config/datastore.h b/include/ipfs/repo/config/datastore.h
index 40bd94f..d7804a8 100644
--- a/include/ipfs/repo/config/datastore.h
+++ b/include/ipfs/repo/config/datastore.h
@@ -2,6 +2,7 @@
#define __DATASTORE_H__
#include
+#include "ipfs/blocks/block.h"
//const char* datastore_default_directory = "datastore";
@@ -19,6 +20,8 @@ struct Datastore {
// function pointers for datastore operations
int (*datastore_open)(int argc, char** argv, struct Datastore* datastore);
int (*datastore_close)(int argc, char** argv, struct Datastore* datastore);
+ int (*datastore_put)(const char* key, struct Block* block, struct Datastore* datastore);
+ //int (*datastore_get)(const char* key, struct Block* block);
// a handle to the datastore "context" used by the datastore
void* handle;
};
diff --git a/include/ipfs/repo/fsrepo/fs_repo.h b/include/ipfs/repo/fsrepo/fs_repo.h
index 1b93b25..89c9692 100644
--- a/include/ipfs/repo/fsrepo/fs_repo.h
+++ b/include/ipfs/repo/fsrepo/fs_repo.h
@@ -16,13 +16,11 @@ struct FSRepo {
char* path;
struct IOCloser* lock_file;
struct RepoConfig* config;
- struct Datastore* data_store;
};
/**
* opens a fsrepo
- * @param repo_path the path to the repo
- * @param repo where to store the repo info
+ * @param repo the repo struct. Should contain the path. This method will do the rest
* @return 0 if there was a problem, otherwise 1
*/
int ipfs_repo_fsrepo_open(struct FSRepo* repo);
@@ -43,10 +41,12 @@ int fs_repo_is_initialized(char* repo_path);
int fs_repo_write_config_file(char* path, struct RepoConfig* config);
/**
- * Initializes a new FSRepo at the given path with the provided config
- * @param repo_path the path to use
- * @param config the information for the config file
- * @returns true(1) on success
+ * constructs the FSRepo struct.
+ * Remember: ipfs_repo_fsrepo_free must be called
+ * @param repo_path the path to the repo
+ * @param config the optional config file. NOTE: if passed, fsrepo_free will free resources of the RepoConfig.
+ * @param repo the struct to allocate memory for
+ * @returns false(0) if something bad happened, otherwise true(1)
*/
int ipfs_repo_fsrepo_new(char* repo_path, struct RepoConfig* config, struct FSRepo** fs_repo);
diff --git a/include/ipfs/repo/fsrepo/lmdb_datastore.h b/include/ipfs/repo/fsrepo/lmdb_datastore.h
index 38920b0..7a0a105 100644
--- a/include/ipfs/repo/fsrepo/lmdb_datastore.h
+++ b/include/ipfs/repo/fsrepo/lmdb_datastore.h
@@ -27,4 +27,11 @@ int repo_fsrepro_lmdb_open(int argc, char** argv, struct Datastore* datastore);
*/
int repo_fsrepo_lmdb_close(int argc, char** argv, struct Datastore* datastore);
+/***
+ * Creates the directory
+ * @param datastore contains the path that needs to be created
+ * @returns true(1) on success
+ */
+int repo_fsrepo_lmdb_create_directory(struct Datastore* datastore);
+
#endif
diff --git a/include/ipfs/repo/repo.h b/include/ipfs/repo/repo.h
deleted file mode 100644
index 23f6364..0000000
--- a/include/ipfs/repo/repo.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef __REPO_H__
-#define __REPO_H__
-
-#include
-
-#include "config/config.h"
-
-/**
- * Get the config
- * @param config a place to put the buffer (must have been pre-allocated)
- * @returns 0 on error
- */
-int repo_get_config(struct RepoConfig* config);
-
-/**
- * Retrieves the config
- * @param config a place to get the information
- * @returns 0 on error
- */
-int repo_set_config(struct RepoConfig* config);
-int repo_set_config_key(char* key, void* value);
-int repo_get_config_key(char* key, void* value);
-int repo_get_datastore(struct Datastore* datastore);
-int repo_get_storage_usage(uint64_t* usage);
-
-#endif // __REPO_H__
diff --git a/repo/Makefile b/repo/Makefile
index e5db459..3277e1f 100644
--- a/repo/Makefile
+++ b/repo/Makefile
@@ -6,7 +6,7 @@ CFLAGS += -g3
endif
DEPS =
-OBJS = repo.o
+OBJS =
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
diff --git a/repo/config/config.c b/repo/config/config.c
index f86554d..61d417d 100644
--- a/repo/config/config.c
+++ b/repo/config/config.c
@@ -87,7 +87,7 @@ int repo_config_get_file_name(char* path, char** result) {
* @param num_bits_for_keypair number of bits for the key pair
* @returns true(1) on success, otherwise 0
*/
-int repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_keypair, char* repo_path) {
+int ipfs_repo_config_init(struct RepoConfig* config, unsigned int num_bits_for_keypair, char* repo_path) {
// identity
int retVal = repo_config_identity_init(config->identity, num_bits_for_keypair);
if (retVal == 0)
diff --git a/repo/config/datastore.c b/repo/config/datastore.c
index eaa874e..732cbf2 100644
--- a/repo/config/datastore.c
+++ b/repo/config/datastore.c
@@ -40,6 +40,7 @@ int ipfs_repo_config_datastore_new(struct Datastore** datastore) {
if (*datastore == NULL)
return 0;
(*datastore)->path = NULL;
+ (*datastore)->handle = NULL;
return 1;
}
diff --git a/repo/fsrepo/fs_repo.c b/repo/fsrepo/fs_repo.c
index 74c0a4e..e20d317 100644
--- a/repo/fsrepo/fs_repo.c
+++ b/repo/fsrepo/fs_repo.c
@@ -109,7 +109,7 @@ int repo_config_write_config_file(char* full_filename, struct RepoConfig* config
* Remember: ipfs_repo_fsrepo_free must be called
* @param repo_path the path to the repo
* @param config the optional config file. NOTE: if passed, fsrepo_free will free resources of the RepoConfig.
- * @param repo the struct to fill in
+ * @param repo the struct to allocate memory for
* @returns false(0) if something bad happened, otherwise true(1)
*/
int ipfs_repo_fsrepo_new(char* repo_path, struct RepoConfig* config, struct FSRepo** repo) {
@@ -140,11 +140,6 @@ int ipfs_repo_fsrepo_new(char* repo_path, struct RepoConfig* config, struct FSRe
return 0;
}
}
- if (ipfs_repo_config_datastore_new(&((*repo)->data_store)) == 0) {
- free(repo_path);
- ipfs_repo_config_free((*repo)->config);
- return 0;
- }
return 1;
}
@@ -159,8 +154,6 @@ int ipfs_repo_fsrepo_free(struct FSRepo* repo) {
free(repo->path);
if (repo->config != NULL)
ipfs_repo_config_free(repo->config);
- if (repo->data_store != NULL)
- ipfs_repo_config_datastore_free(repo->data_store);
free(repo);
}
return 1;
@@ -347,7 +340,7 @@ int fs_repo_open_config(struct FSRepo* repo) {
return 0;
}
// fill FSRepo struct
- repo->config = malloc(sizeof(struct RepoConfig));
+ // allocation done by fsrepo_new... repo->config = malloc(sizeof(struct RepoConfig));
// Identity
int curr_pos = _find_token(data, tokens, num_tokens, 0, "Identity");
if (curr_pos < 0) {
@@ -389,7 +382,7 @@ int fs_repo_open_config(struct FSRepo* repo) {
* @returns true(1) on success
*/
int fs_repo_setup_lmdb_datastore(struct FSRepo* repo) {
- return repo_fsrepo_lmdb_cast(repo->data_store);
+ return repo_fsrepo_lmdb_cast(repo->config->datastore);
}
/***
@@ -401,10 +394,7 @@ int fs_repo_open_datastore(struct FSRepo* repo) {
int argc = 0;
char** argv = NULL;
- // copy struct from config area to this area
- repo->data_store = repo->config->datastore;
-
- if (strncmp(repo->data_store->type, "lmdb", 4) == 0) {
+ if (strncmp(repo->config->datastore->type, "lmdb", 4) == 0) {
// this is a LightningDB. Open it.
int retVal = fs_repo_setup_lmdb_datastore(repo);
if (retVal == 0)
@@ -414,7 +404,7 @@ int fs_repo_open_datastore(struct FSRepo* repo) {
return 0;
}
- int retVal = repo->data_store->datastore_open(argc, argv, repo->data_store);
+ int retVal = repo->config->datastore->datastore_open(argc, argv, repo->config->datastore);
// do specific datastore cleanup here if needed
@@ -463,6 +453,14 @@ int fs_repo_is_initialized(char* repo_path) {
return fs_repo_is_initialized_unsynced(repo_path);
}
+int ipfs_repo_fsrepo_datastore_init(struct FSRepo* fs_repo) {
+ // make the directory
+ repo_fsrepo_lmdb_create_directory(fs_repo->config->datastore);
+
+ // fill in the function prototypes
+ repo_fsrepo_lmdb_cast(fs_repo->config->datastore);
+}
+
/**
* Initializes a new FSRepo at the given path with the provided config
* @param path the path to use
@@ -481,7 +479,7 @@ int ipfs_repo_fsrepo_init(struct FSRepo* repo) {
return 0;
// TODO: Implement this method
- //retVal = fs_repo_defaultds_init(path, config);
+ retVal = ipfs_repo_fsrepo_datastore_init(repo);
if (retVal == 0)
return 0;
diff --git a/repo/fsrepo/lmdb_datastore.c b/repo/fsrepo/lmdb_datastore.c
index c3f0cf9..5e9d902 100644
--- a/repo/fsrepo/lmdb_datastore.c
+++ b/repo/fsrepo/lmdb_datastore.c
@@ -3,10 +3,55 @@
*/
#include
+#include
+#include
+#include
#include "lmdb.h"
#include "ipfs/repo/fsrepo/lmdb_datastore.h"
+/**
+ * Write a block to the datastore with the specified key
+ * @param key the key
+ * @param block the block to be written
+ * @returns true(1) on success
+ */
+int repo_fsrepo_lmdb_put(const char* key, struct Block* block, struct Datastore* datastore) {
+ int retVal;
+ MDB_txn* mdb_txn;
+ MDB_dbi mdb_dbi;
+ struct MDB_val db_key;
+ struct MDB_val db_value;
+
+ MDB_env* mdb_env = (MDB_env*)datastore->handle;
+ if (mdb_env == NULL)
+ return 0;
+
+ // open transaction
+ retVal = mdb_txn_begin(mdb_env, NULL, 0, &mdb_txn);
+ if (retVal != 0)
+ return 0;
+ retVal = mdb_dbi_open(mdb_txn, NULL, 0, &mdb_dbi);
+ if (retVal != 0)
+ return 0;
+
+ // write
+ db_key.mv_size = strlen(key) + 1;
+ db_key.mv_data = (char*)key;
+ db_value.mv_size = block->data_length;
+ db_value.mv_data = block->data;
+ retVal = mdb_put(mdb_txn, mdb_dbi, &db_key, &db_value, MDB_NODUPDATA);
+ if (retVal != 0)
+ return 0;
+
+ // cleanup
+ mdb_dbi_close(mdb_env, mdb_dbi);
+ mdb_txn_commit(mdb_txn);
+ return 1;
+}
+
+
+
/**
* Open an lmdb database with the given parameters.
* Note: for now, the parameters are not used
@@ -23,7 +68,7 @@ int repo_fsrepro_lmdb_open(int argc, char** argv, struct Datastore* datastore) {
}
// open the environment
- retVal = mdb_env_open(mdb_env, datastore->path, 0, 755);
+ retVal = mdb_env_open(mdb_env, datastore->path, 0, S_IRWXU);
if (retVal < 0) {
mdb_env_close(mdb_env);
return 0;
@@ -55,6 +100,17 @@ int repo_fsrepo_lmdb_close(int argc, char** argv, struct Datastore* datastore) {
int repo_fsrepo_lmdb_cast(struct Datastore* datastore) {
datastore->datastore_open = &repo_fsrepro_lmdb_open;
datastore->datastore_close = &repo_fsrepo_lmdb_close;
+ datastore->datastore_put = &repo_fsrepo_lmdb_put;
+ //datastore->datastore_get = &repo_fsrepo_lmdb_get;
return 1;
}
+/***
+ * Creates the directory
+ * @param datastore contains the path that needs to be created
+ * @returns true(1) on success
+ */
+int repo_fsrepo_lmdb_create_directory(struct Datastore* datastore) {
+ return mkdir(datastore->path, S_IRWXU) == 0;
+}
+
diff --git a/repo/repo.c b/repo/repo.c
deleted file mode 100644
index 67e0a61..0000000
--- a/repo/repo.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "ipfs/repo/repo.h"
-
-int repo_get_config(struct RepoConfig* config) {
- return 0;
-}
-
diff --git a/test/Makefile b/test/Makefile
index 37d3fe4..61045ae 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -8,7 +8,8 @@ OBJS = testit.o ../cmd/ipfs/init.o ../commands/argument.o ../commands/command_op
../repo/config/bootstrap_peers.o ../repo/config/datastore.o ../repo/config/gateway.o \
../repo/config/addresses.o ../repo/config/swarm.o ../repo/config/peer.o \
../thirdparty/ipfsaddr/ipfs_addr.o ../cid/cid.o ../multibase/multibase.o \
- ../flatfs/flatfs.o ../datastore/ds_helper.o
+ ../flatfs/flatfs.o ../blocks/block.o ../blocks/blockstore.o \
+ ../datastore/ds_helper.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
diff --git a/test/repo/test_repo_config.h b/test/repo/test_repo_config.h
index 612eae8..ef5dcc7 100644
--- a/test/repo/test_repo_config.h
+++ b/test/repo/test_repo_config.h
@@ -32,7 +32,7 @@ int test_repo_config_init() {
if (retVal == 0)
return 0;
- retVal = repo_config_init(repoConfig, 2048, "/Users/JohnJones/.ipfs");
+ retVal = ipfs_repo_config_init(repoConfig, 2048, "/Users/JohnJones/.ipfs");
if (retVal == 0)
return 0;
@@ -77,7 +77,7 @@ int test_repo_config_write() {
// now build a new one
struct RepoConfig* repoConfig;
ipfs_repo_config_new(&repoConfig);
- if (!repo_config_init(repoConfig, 2048, "/tmp/.ipfs")) {
+ if (!ipfs_repo_config_init(repoConfig, 2048, "/tmp/.ipfs")) {
ipfs_repo_config_free(repoConfig);
return 0;
}
diff --git a/test/storage/test_blocks.h b/test/storage/test_blocks.h
new file mode 100644
index 0000000..2636538
--- /dev/null
+++ b/test/storage/test_blocks.h
@@ -0,0 +1,36 @@
+#include "ipfs/blocks/block.h"
+
+int test_blocks_new() {
+ const char* input = "Hello, World!";
+ int retVal = 0;
+ struct Block* block;
+ retVal = ipfs_blocks_block_new(input, strlen(input) + 1, &block);
+ if (retVal == 0)
+ return 0;
+
+ // now examine the block
+ if (strcmp(block->data, input) != 0)
+ return 0;
+
+ if (block->data_length != strlen(input) + 1)
+ return 0;
+
+ if (block->cid->codec != CID_PROTOBUF)
+ return 0;
+
+ if (block->cid->version != 0)
+ return 0;
+
+ if (block->cid->hash_length != 32)
+ return 0;
+
+ unsigned char result_hash[32] = {33, 153, 66, 187, 124, 250, 87, 12, 12, 73, 43, 247, 175, 153, 10, 51, 192, 195, 218, 69, 220, 170, 105, 179, 195, 0, 203, 213, 172, 3, 244, 10 };
+ for(int i = 0; i < 32; i++) {
+ if (block->cid->hash[i] != result_hash[i])
+ return 0;
+ }
+
+ retVal = ipfs_blocks_block_free(block);
+
+ return 1;
+}
diff --git a/test/storage/test_blockstore.h b/test/storage/test_blockstore.h
new file mode 100644
index 0000000..149f218
--- /dev/null
+++ b/test/storage/test_blockstore.h
@@ -0,0 +1,20 @@
+#include
+
+#include "ipfs/blocks/blockstore.h"
+#include "ipfs/blocks/block.h"
+
+int test_blockstore_put() {
+ const unsigned char* input_string = "Hello, World!";
+ struct Block* input_block;
+ int retVal = 0;
+
+ retVal = ipfs_blocks_block_new(input_string, strlen((const char*)input_string) + 1, &input_block);
+ if (retVal == 0)
+ return 0;
+
+ retVal = ipfs_blockstore_put(input_block);
+ if (retVal == 0)
+ return 0;
+
+ return 1;
+}
diff --git a/test/storage/test_datastore.h b/test/storage/test_datastore.h
new file mode 100644
index 0000000..fdd81fa
--- /dev/null
+++ b/test/storage/test_datastore.h
@@ -0,0 +1,148 @@
+#include "libp2p/crypto/encoding/base32.h"
+#include "ipfs/datastore/ds_helper.h"
+#include "ipfs/blocks/block.h"
+#include "ipfs/repo/config/config.h"
+#include "ipfs/repo/fsrepo/fs_repo.h"
+
+#include
+#include
+
+int remove_directory(const char *path)
+{
+ DIR *d = opendir(path);
+ size_t path_len = strlen(path);
+ int r = -1;
+
+ if (d)
+ {
+ struct dirent *p;
+
+ r = 0;
+
+ while (!r && (p=readdir(d)))
+ {
+ int r2 = -1;
+ char *buf;
+ size_t len;
+
+ /* Skip the names "." and ".." as we don't want to recurse on them. */
+ if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, ".."))
+ {
+ continue;
+ }
+
+ len = path_len + strlen(p->d_name) + 2;
+ buf = malloc(len);
+
+ if (buf)
+ {
+ struct stat statbuf;
+
+ snprintf(buf, len, "%s/%s", path, p->d_name);
+
+ if (!stat(buf, &statbuf))
+ {
+ if (S_ISDIR(statbuf.st_mode))
+ {
+ r2 = remove_directory(buf);
+ }
+ else
+ {
+ r2 = unlink(buf);
+ }
+ }
+
+ free(buf);
+ }
+
+ r = r2;
+ }
+
+ closedir(d);
+ }
+
+ if (!r)
+ {
+ r = rmdir(path);
+ }
+
+ return r;
+}
+
+int make_ipfs_repository(struct FSRepo* fs_repo) {
+ int retVal;
+ struct RepoConfig* repo_config;
+
+ unlink("/tmp/.ipfs/config");
+ remove_directory("/tmp/.ipfs/datastore");
+ remove_directory("/tmp/.ipfs/blockstore");
+
+ // build a default repo config
+ retVal = ipfs_repo_config_new(&repo_config);
+ if (retVal == 0)
+ return 0;
+ retVal = ipfs_repo_config_init(repo_config, 2048, "/tmp/.ipfs");
+ if (retVal == 0)
+ return 0;
+ // now the fs_repo
+ retVal = ipfs_repo_fsrepo_new("/tmp/.ipfs", repo_config, &fs_repo);
+ if (retVal == 0)
+ return 0;
+ // this builds a new repo
+ retVal = ipfs_repo_fsrepo_init(fs_repo);
+ if (retVal == 0)
+ return 0;
+
+ // clean up
+ ipfs_repo_fsrepo_free(fs_repo);
+ // this is cleaned up by fsrepo_free
+ //ipfs_repo_config_free(repo_config);
+
+ // make sure the repository exists
+ retVal = os_utils_file_exists("/tmp/.ipfs/config");
+ return retVal;
+}
+
+int test_ipfs_datastore_put() {
+ struct Block* block;
+ int retVal;
+ const unsigned char* input = "Hello, world!";
+
+ // build the ipfs repository, then shut it down, so we can start fresh
+ struct FSRepo* fs_repo;
+ retVal = make_ipfs_repository(fs_repo);
+ ipfs_repo_fsrepo_free(fs_repo);
+ if (retVal == 0)
+ return 0;
+
+ // build the block
+ retVal = ipfs_blocks_block_new(input, strlen((char*)input), &block);
+ if (retVal == 0)
+ return 0;
+
+ // generate the key
+ size_t key_length = libp2p_crypto_encoding_base32_encode_size(block->data_length);
+ unsigned char key[key_length];
+ retVal = ipfs_datastore_helper_ds_key_from_binary(block->data, block->data_length, &key[0], key_length, &key_length);
+ if (retVal == 0)
+ return 0;
+
+ // open the repository
+ retVal = ipfs_repo_fsrepo_new("/tmp/.ipfs", NULL, &fs_repo);
+ if (retVal == 0)
+ return 0;
+ retVal = ipfs_repo_fsrepo_open(fs_repo);
+ if (retVal == 0)
+ return 0;
+
+ // send to Put with key
+ retVal = fs_repo->config->datastore->datastore_put(key, block, fs_repo->config->datastore);
+ if (retVal == 0)
+ return 0;
+
+ // save the block
+
+ // check the results
+
+ return 1;
+}
diff --git a/test/testit.c b/test/testit.c
index b005073..7b21f52 100644
--- a/test/testit.c
+++ b/test/testit.c
@@ -6,6 +6,8 @@
#include "cid/test_cid.h"
#include "flatfs/test_flatfs.h"
#include "storage/test_ds_helper.h"
+#include "storage/test_datastore.h"
+#include "storage/test_blocks.h"
int testit(const char* name, int (*func)(void)) {
printf("Testing %s...\n", name);
@@ -19,6 +21,7 @@ int testit(const char* name, int (*func)(void)) {
int main(int argc, char** argv) {
int counter = 0;
+ /*
counter += testit("test_cid_new_free", test_cid_new_free);
counter += testit("test_cid_cast_multihash", test_cid_cast_multihash);
counter += testit("test_cid_cast_non_multihash", test_cid_cast_non_multihash);
@@ -35,6 +38,9 @@ int main(int argc, char** argv) {
counter += testit("test_flatfs_get_filename", test_flatfs_get_filename);
counter += testit("test_flatfs_get_full_filename", test_flatfs_get_full_filename);
counter += testit("test_ds_key_from_binary", test_ds_key_from_binary);
+ counter += testit("test_blocks_new", test_blocks_new);
+ */
+ counter += testit("test_ipfs_datastore_put", test_ipfs_datastore_put);
if (counter > 0) {
printf("***** There were %d failed test(s) *****\n", counter);
} else {