Saving directories

This commit is contained in:
jmjatlanta 2016-12-28 22:45:35 -05:00
parent 9d77b2709f
commit fa3dd77e96
5 changed files with 171 additions and 25 deletions

View file

@ -4,6 +4,7 @@
#include "ipfs/importer/importer.h" #include "ipfs/importer/importer.h"
#include "ipfs/merkledag/merkledag.h" #include "ipfs/merkledag/merkledag.h"
#include "ipfs/os/utils.h"
#include "ipfs/repo/fsrepo/fs_repo.h" #include "ipfs/repo/fsrepo/fs_repo.h"
#include "ipfs/unixfs/unixfs.h" #include "ipfs/unixfs/unixfs.h"
@ -150,6 +151,26 @@ size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs
return bytes_read; return bytes_read;
} }
/**
* Prints to the console the results of a node import
* @param node the node imported
* @param file_name the name of the file
* @returns true(1) if successful, false(0) if couldn't generate the MultiHash to be displayed
*/
int ipfs_import_print_node_results(const struct Node* node, const char* file_name) {
// give some results to the user
//TODO: if directory_entry is itself a directory, traverse and report files
int buffer_len = 100;
unsigned char buffer[buffer_len];
if (ipfs_cid_hash_to_base58(node->hash, node->hash_size, buffer, buffer_len) == 0) {
printf("Unable to generate hash for file %s.\n", file_name);
return 0;
}
printf("added %s %s\n", buffer, file_name);
return 1;
}
/** /**
* Creates a node based on an incoming file or directory * Creates a node based on an incoming file or directory
* NOTE: this can be called recursively for directories * NOTE: this can be called recursively for directories
@ -167,13 +188,42 @@ int ipfs_import_file(const char* fileName, struct Node** parent_node, struct FSR
int retVal = 1; int retVal = 1;
int bytes_read = MAX_DATA_SIZE; int bytes_read = MAX_DATA_SIZE;
size_t total_size = 0; size_t total_size = 0;
unsigned int isDirectory = 0;
//TODO: determine if this file is actually a directory if (os_utils_is_directory(fileName)) {
if (isDirectory) { // initialize parent_node as a directory
if (ipfs_node_create_directory(parent_node) == 0)
return 0;
// get list of files // get list of files
// process each file struct FileList* first = os_utils_list_directory(fileName);
// add file as link to parent_node struct FileList* next = first;
while (next != NULL) {
// process each file. NOTE: could be an embedded directory
struct Node* file_node;
size_t filename_len = strlen(fileName) + strlen(next->file_name) + 2;
char full_file_name[filename_len];
os_utils_filepath_join(fileName, next->file_name, full_file_name, filename_len);
if (ipfs_import_file(full_file_name, &file_node, fs_repo) == 0) {
ipfs_node_free(*parent_node);
os_utils_free_file_list(first);
return 0;
}
// TODO: probably need to display what was imported
ipfs_import_print_node_results(file_node, next->file_name);
// TODO: Determine what needs to be done if this file_node is a file, a split file, or a directory
// Create link from file_node
struct NodeLink* file_node_link;
ipfs_node_link_create(next->file_name, file_node->hash, file_node->hash_size, &file_node_link);
file_node_link->t_size = file_node->data_size;
// add file_node as link to parent_node
ipfs_node_add_link(*parent_node, file_node_link);
// clean up file_node
ipfs_node_free(file_node);
// move to next file in list
next = next->next;
} // while going through files
// save the parent_node (the directory)
size_t bytes_written;
ipfs_merkledag_add(*parent_node, fs_repo, &bytes_written);
} else { } else {
// process this file // process this file
FILE* file = fopen(fileName, "rb"); FILE* file = fopen(fileName, "rb");
@ -192,12 +242,6 @@ int ipfs_import_file(const char* fileName, struct Node** parent_node, struct FSR
} }
// a linked list to store filenames
struct FileList {
char* file_name;
struct FileList* next;
};
/** /**
* called from the command line to import multiple files or directories * called from the command line to import multiple files or directories
* @param argc the number of arguments * @param argc the number of arguments
@ -248,18 +292,8 @@ int ipfs_import_files(int argc, char** argv) {
struct Node* directory_entry = NULL; struct Node* directory_entry = NULL;
retVal = ipfs_import_file(current->file_name, &directory_entry, fs_repo); retVal = ipfs_import_file(current->file_name, &directory_entry, fs_repo);
// give some results to the user ipfs_import_print_node_results(directory_entry, current->file_name);
int buffer_len = 100; // cleanup
unsigned char buffer[buffer_len];
retVal = ipfs_cid_hash_to_base58(directory_entry->hash, directory_entry->hash_size, buffer, buffer_len);
if (retVal == 0) {
printf("Unable to generate hash\n");
ipfs_node_free(directory_entry);
ipfs_repo_fsrepo_free(fs_repo);
return 0;
}
printf("added %s %s\n", buffer, current->file_name);
//TODO: cleanup
ipfs_node_free(directory_entry); ipfs_node_free(directory_entry);
current = current->next; current = current->next;
} }
@ -276,3 +310,4 @@ int ipfs_import_files(int argc, char** argv) {
return retVal; return retVal;
} }

View file

@ -127,12 +127,21 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc
* Node Functions * Node Functions
*===================================================================================*/ *===================================================================================*/
/*ipfs_node_new /****
* Creates an empty node, allocates the required memory * Creates an empty node, allocates the required memory
* Returns a fresh new node with no data set in it. * @param node the pointer to the memory allocated
* @returns true(1) on success, otherwise false(0)
*/ */
int ipfs_node_new(struct Node** node); int ipfs_node_new(struct Node** node);
/***
* Allocates memory for a node, and sets the data section to indicate
* that this node is a directory
* @param node the node to initialize
* @returns true(1) on success, otherwise false(0)
*/
int ipfs_node_create_directory(struct Node** node);
/** /**
* sets the Cid into the struct element titled cached * sets the Cid into the struct element titled cached
* @param node the node to work with * @param node the node to work with

View file

@ -8,6 +8,18 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
/**
* a linked list to store filenames
*/
struct FileList {
char* file_name;
struct FileList* next;
};
struct FileList* os_utils_list_directory(const char* path);
// frees memory used by creating a FileList linked list
int os_utils_free_file_list(struct FileList* first);
/** /**
* get an environment varible from the os * get an environment varible from the os
* @param variable the variable to look for * @param variable the variable to look for
@ -38,4 +50,11 @@ int os_utils_directory_writeable(const char* path);
int os_utils_directory_exists(const char* path); int os_utils_directory_exists(const char* path);
/**
* Determine if the path presented is actually a directory
* @param file_name the path to examine
* @returns true(1) if file_name is actually a directory
*/
int os_utils_is_directory(const char* file_name);
#endif /* utils_h */ #endif /* utils_h */

View file

@ -356,6 +356,35 @@ int ipfs_node_new(struct Node** node)
return 1; return 1;
} }
/***
* Allocates memory for a node, and sets the data section to indicate
* that this node is a directory
* @param node the node to initialize
* @returns true(1) on success, otherwise false(0)
*/
int ipfs_node_create_directory(struct Node** node) {
// initialize parent_node
if (ipfs_node_new(node) == 0)
return 0;
// put a UnixFS protobuf in the data section
struct UnixFS* unix_fs;
if (ipfs_unixfs_new(&unix_fs) == 0) {
ipfs_node_free(*node);
return 0;
}
unix_fs->data_type = UNIXFS_DIRECTORY;
size_t protobuf_len = ipfs_unixfs_protobuf_encode_size(unix_fs);
unsigned char protobuf[protobuf_len];
if (ipfs_unixfs_protobuf_encode(unix_fs, protobuf, protobuf_len, &protobuf_len) == 0) {
ipfs_node_free(*node);
ipfs_unixfs_free(unix_fs);
return 0;
}
ipfs_unixfs_free(unix_fs);
ipfs_node_set_data(*node, protobuf, protobuf_len);
return 1;
}
/** /**
* Set the cached struct element * Set the cached struct element
* @param node the node to be modified * @param node the node to be modified

View file

@ -2,9 +2,11 @@
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h> #include <pwd.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <dirent.h>
/** /**
* get an environment varible from the os * get an environment varible from the os
@ -56,6 +58,58 @@ int os_utils_directory_exists(const char* directory_name) {
return 0; return 0;
} }
int os_utils_is_directory(const char* file_name) {
struct stat path_stat;
stat(file_name, &path_stat);
return S_ISDIR(path_stat.st_mode) != 0;
}
struct FileList* os_utils_list_directory(const char* path) {
DIR* dp;
struct dirent *ep;
struct FileList* first = NULL;
struct FileList* last = NULL;
struct FileList* next = NULL;
dp = opendir(path);
if (dp != NULL) {
while ( (ep = readdir(dp)) ) {
if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) {
// grab the data
next = (struct FileList*)malloc(sizeof(struct FileList));
next->file_name = malloc(strlen(ep->d_name) + 1);
strcpy(next->file_name, ep->d_name);
next->next = NULL;
// put it in the appropriate spot
if (first == NULL) {
first = next;
last = next;
} else {
last->next = next;
last = next;
}
} // not dealing with . or ..
} // while
closedir(dp);
}
return first;
}
int os_utils_free_file_list(struct FileList* first) {
if (first != NULL) {
struct FileList* next = first;
struct FileList* last = NULL;
while (next != NULL) {
last = next->next;
free(next);
next = last;
}
}
return 1;
}
int os_utils_directory_writeable(const char* path) { int os_utils_directory_writeable(const char* path) {
int result = access(path, W_OK); int result = access(path, W_OK);
return result == 0; return result == 0;