diff --git a/core/daemon.c b/core/daemon.c index fe91fd0..f94ed4a 100644 --- a/core/daemon.c +++ b/core/daemon.c @@ -9,6 +9,7 @@ #include "ipfs/core/ipfs_node.h" #include "ipfs/core/bootstrap.h" #include "ipfs/repo/fsrepo/fs_repo.h" +#include "ipfs/repo/init.h" #include "libp2p/utils/logger.h" int ipfs_daemon_start(char* repo_path) { @@ -38,8 +39,9 @@ int ipfs_daemon_start(char* repo_path) { local_node.identity = fs_repo->config->identity; // Set null router param + struct MultiAddress *ma = multiaddress_new_from_string(fs_repo->config->addresses->swarm_head->item); + listen_param.port = multiaddress_get_ip_port(ma); listen_param.ipv4 = 0; // ip 0.0.0.0, all interfaces - listen_param.port = 4001; listen_param.local_node = &local_node; // Create pthread for swarm listener. @@ -72,9 +74,17 @@ int ipfs_daemon_start(char* repo_path) { int ipfs_daemon (int argc, char **argv) { + char* repo_path = NULL; + + if (!ipfs_repo_get_directory(argc, argv, &repo_path)) { + fprintf(stderr, "Unable to open repo: %s\n", repo_path); + return 0; + } + libp2p_logger_add_class("peerstore"); libp2p_logger_add_class("providerstore"); libp2p_logger_add_class("daemon"); libp2p_logger_add_class("online"); - return ipfs_daemon_start(NULL); + + return ipfs_daemon_start(repo_path); } diff --git a/core/ping.c b/core/ping.c index dd80b8d..acf613d 100644 --- a/core/ping.c +++ b/core/ping.c @@ -10,6 +10,7 @@ #include "libp2p/secio/secio.h" #include "libp2p/routing/dht_protocol.h" #include "ipfs/repo/fsrepo/fs_repo.h" +#include "ipfs/repo/init.h" #include "ipfs/core/ipfs_node.h" #include "ipfs/routing/routing.h" #include "ipfs/importer/resolver.h" @@ -27,11 +28,16 @@ int ipfs_ping (int argc, char **argv) struct Libp2pPeer* peer_to_ping = NULL; char* id = NULL; struct FSRepo* fs_repo = NULL; + char* repo_path = NULL; // sanity check if (argc < 3) goto exit; + if (!ipfs_repo_get_directory(argc, argv, &repo_path)) { + fprintf(stderr, "Unable to open repo: %s\n", repo_path); + return 0; + } // read the configuration if (!ipfs_repo_fsrepo_new(NULL, NULL, &fs_repo)) goto exit; diff --git a/importer/exporter.c b/importer/exporter.c index bf0c73f..8cf4311 100644 --- a/importer/exporter.c +++ b/importer/exporter.c @@ -5,17 +5,19 @@ #include "ipfs/merkledag/merkledag.h" #include "ipfs/merkledag/node.h" #include "ipfs/repo/fsrepo/fs_repo.h" +#include "ipfs/repo/init.h" /** * pull objects from ipfs */ -/** - * get a file by its hash, and write the data to a file + +/*** + * Get a file by its hash, and write the data to a filestream * @param hash the base58 multihash of the cid - * @param file_name the file name to write to - * @returns true(1) on success + * @param file_descriptor where to write + * @param fs_repo the repo */ -int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, const struct FSRepo* fs_repo) { +int ipfs_exporter_to_filestream(const unsigned char* hash, FILE* file_descriptor, 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) { @@ -32,20 +34,13 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons // no longer need the cid ipfs_cid_free(cid); - // process blocks - FILE* file = fopen(file_name, "wb"); - if (file == NULL) { - ipfs_node_free(read_node); - return 0; - } - if (read_node->head_link == NULL) { // convert the node's data into a UnixFS data block struct UnixFS* unix_fs; ipfs_unixfs_protobuf_decode(read_node->data, read_node->data_size, &unix_fs); - size_t bytes_written = fwrite(unix_fs->bytes, 1, unix_fs->bytes_size, file); + size_t bytes_written = fwrite(unix_fs->bytes, 1, unix_fs->bytes_size, file_descriptor); if (bytes_written != unix_fs->bytes_size) { - fclose(file); + fclose(file_descriptor); ipfs_node_free(read_node); ipfs_unixfs_free(unix_fs); return 0; @@ -56,16 +51,16 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons struct Node* link_node = NULL; while (link != NULL) { if ( ipfs_merkledag_get(link->hash, link->hash_size, &link_node, fs_repo) == 0) { - fclose(file); + fclose(file_descriptor); ipfs_node_free(read_node); return 0; } struct UnixFS* unix_fs; ipfs_unixfs_protobuf_decode(link_node->data, link_node->data_size, &unix_fs); - size_t bytes_written = fwrite(unix_fs->bytes, 1, unix_fs->bytes_size, file); + size_t bytes_written = fwrite(unix_fs->bytes, 1, unix_fs->bytes_size, file_descriptor); if (bytes_written != unix_fs->bytes_size) { ipfs_node_free(link_node); - fclose(file); + fclose(file_descriptor); ipfs_node_free(read_node); ipfs_unixfs_free(unix_fs); return 0; @@ -75,7 +70,7 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons link = link->next; } } - fclose(file); + fclose(file_descriptor); if (read_node != NULL) ipfs_node_free(read_node); @@ -83,6 +78,22 @@ int ipfs_exporter_to_file(const unsigned char* hash, const char* file_name, cons 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_file(const unsigned char* hash, const char* file_name, const struct FSRepo* fs_repo) { + // process blocks + FILE* file = fopen(file_name, "wb"); + if (file == NULL) { + return 0; + } + return ipfs_exporter_to_filestream(hash, file, fs_repo); +} + /** * get a file by its hash, and write the data to a file * @param hash the base58 multihash of the cid @@ -135,12 +146,19 @@ int ipfs_exporter_to_console(const unsigned char* hash, const struct FSRepo* fs_ */ int ipfs_exporter_object_get(int argc, char** argv) { struct FSRepo* fs_repo = NULL; + char* repo_path = NULL; - // open the repo - int retVal = ipfs_repo_fsrepo_new(NULL, NULL, &fs_repo); + if (!ipfs_repo_get_directory(argc, argv, &repo_path)) { + fprintf(stderr, "Unable to open repository: %s\n", repo_path); + return 0; + } + + // build the struct + int retVal = ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo); if (retVal == 0) { return 0; } + // open the repo retVal = ipfs_repo_fsrepo_open(fs_repo); if (retVal == 0) { return 0; @@ -183,9 +201,15 @@ int ipfs_exporter_cat_node(struct Node* node, const struct FSRepo* fs_repo) { */ int ipfs_exporter_object_cat(int argc, char** argv) { struct FSRepo* fs_repo = NULL; + char* repo_dir = NULL; + + if (!ipfs_repo_get_directory(argc, argv, &repo_dir)) { + fprintf(stderr, "Unable to open repo: %s\n", repo_dir); + return 0; + } // open the repo - int retVal = ipfs_repo_fsrepo_new(NULL, NULL, &fs_repo); + int retVal = ipfs_repo_fsrepo_new(repo_dir, NULL, &fs_repo); if (retVal == 0) { return 0; } diff --git a/importer/importer.c b/importer/importer.c index 229275b..972c91f 100644 --- a/importer/importer.c +++ b/importer/importer.c @@ -6,6 +6,7 @@ #include "ipfs/merkledag/merkledag.h" #include "libp2p/os/utils.h" #include "ipfs/repo/fsrepo/fs_repo.h" +#include "ipfs/repo/init.h" #include "ipfs/unixfs/unixfs.h" #define MAX_DATA_SIZE 262144 // 1024 * 256; @@ -332,11 +333,22 @@ int ipfs_import_files(int argc, char** argv) { } // open the repo - int retVal = ipfs_repo_fsrepo_new(NULL, NULL, &fs_repo); - if (retVal == 0) { + char* repo_path = NULL; + if (!ipfs_repo_get_directory(argc, argv, &repo_path)) { + // dir doesn't exist + fprintf(stderr, "Repo does not exist: %s\n", repo_path); return 0; } - retVal = ipfs_repo_fsrepo_open(fs_repo); + if (!ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo)) { + fprintf(stderr, "Unable to build the repo struct: %s\n", repo_path); + return 0; + } + if (!ipfs_repo_fsrepo_open(fs_repo)) { + fprintf(stderr, "Unable to open repository: %s\n", repo_path); + return 0; + } + + int retVal = 0; // import the file(s) struct FileList* current = first; diff --git a/include/ipfs/repo/init.h b/include/ipfs/repo/init.h index c49fdc0..6be0212 100644 --- a/include/ipfs/repo/init.h +++ b/include/ipfs/repo/init.h @@ -15,3 +15,14 @@ int make_ipfs_repository(const char* path); * @returns true(1) on success */ int ipfs_repo_init(int argc, char** argv); + +/** + * Get the correct repo directory. Looks in all the appropriate places + * for the ipfs directory. + * @param argc number of command line arguments + * @param argv command line arguments + * @param repo_dir the results. This will point to the [IPFS_PATH]/.ipfs directory + * @returns true(1) if the directory is there, false(0) if it is not. + */ +int ipfs_repo_get_directory(int argc, char** argv, char** repo_dir); + diff --git a/repo/init.c b/repo/init.c index 9365bd9..8e29d0e 100644 --- a/repo/init.c +++ b/repo/init.c @@ -6,6 +6,57 @@ #include "ipfs/repo/config/config.h" #include "ipfs/repo/fsrepo/fs_repo.h" +/** + * Get the correct repo home directory. This first looks at the + * command line, then the IPFS_PATH environment variable, + * then the user's home directory. This is where the .ipfs directory + * is or will be. + * @param argc number of command line parameters + * @param argv command line parameters + * @returns the repo home directory + */ +char* ipfs_repo_get_home_directory(int argc, char** argv) { + char *result = NULL; + // first check the command line + for(int i = 0; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--config") == 0) { + if (i + 1 < argc) { + result = argv[i+1]; + break; + } + } + } + if (result == NULL) { // we didn't pass it on the command line + // check IPFS_PATH + result = os_utils_getenv("IPFS_PATH"); + } + if (result == NULL) { // not on command line nor environment var. + result = os_utils_get_homedir(); + } + return result; +} + +/** + * Get the correct repo directory. Looks in all the appropriate places + * for the ipfs directory. + * @param argc number of command line arguments + * @param argv command line arguments + * @param repo_dir the results. This will point to the [IPFS_PATH]/.ipfs directory + * @returns true(1) if the directory is there, false(0) if it is not. + */ +int ipfs_repo_get_directory(int argc, char** argv, char** repo_dir) { + char* home = ipfs_repo_get_home_directory(argc, argv); + int dir_len = strlen(home) + 7; + *repo_dir = malloc(dir_len); + os_utils_filepath_join(home, ".ipfs", *repo_dir, dir_len); + return os_utils_directory_exists(*repo_dir); +} + +/** + * Make an IPFS directory at the passed in path + * @param path the path + * @returns true(1) on success, false(0) on failure + */ int make_ipfs_repository(const char* path) { int retVal; char currDirectory[1024]; @@ -47,41 +98,27 @@ int make_ipfs_repository(const char* path) { return retVal; } - /** * Initialize a repository + * @param argc number of command line arguments + * @param argv command line arguments + * @returns true(1) on succes, false(0) otherwise */ int ipfs_repo_init(int argc, char** argv) { - // the default is the user's home directory - char* home_directory = os_utils_get_homedir(); - //allow user to pass directory on command line - if (argc > 2) { - home_directory = argv[2]; - } else { - // check the IPFS_PATH - char* temp = os_utils_getenv("IPFS_PATH"); - if (temp != NULL) - home_directory = temp; - } - // get the full path - int dir_len = strlen(home_directory) + 7; - char dir[dir_len]; - strcpy(dir, home_directory); - os_utils_filepath_join(home_directory, ".ipfs", dir, dir_len); - // make sure it doesn't already exist - if (os_utils_file_exists(dir)) { - printf("Directory already exists: %s\n", dir); + char* repo_directory = NULL; + if (ipfs_repo_get_directory(argc, argv, &repo_directory)) { + printf("Directory already exists: %s\n", repo_directory); return 0; } // make the directory #ifdef __MINGW32__ - if (mkdir(dir) == -1) { + if (mkdir(repo_directory) == -1) { #else - if (mkdir(dir, S_IRWXU) == -1) { + if (mkdir(repo_directory, S_IRWXU) == -1) { #endif - printf("Unable to create the directory: %s\n", dir); + printf("Unable to create the directory: %s\n", repo_directory); return 0; } // make the repository - return make_ipfs_repository(dir); + return make_ipfs_repository(repo_directory); }