Saving directories
This commit is contained in:
parent
9d77b2709f
commit
fa3dd77e96
5 changed files with 171 additions and 25 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "ipfs/importer/importer.h"
|
||||
#include "ipfs/merkledag/merkledag.h"
|
||||
#include "ipfs/os/utils.h"
|
||||
#include "ipfs/repo/fsrepo/fs_repo.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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 bytes_read = MAX_DATA_SIZE;
|
||||
size_t total_size = 0;
|
||||
unsigned int isDirectory = 0;
|
||||
|
||||
//TODO: determine if this file is actually a directory
|
||||
if (isDirectory) {
|
||||
if (os_utils_is_directory(fileName)) {
|
||||
// initialize parent_node as a directory
|
||||
if (ipfs_node_create_directory(parent_node) == 0)
|
||||
return 0;
|
||||
// get list of files
|
||||
// process each file
|
||||
// add file as link to parent_node
|
||||
struct FileList* first = os_utils_list_directory(fileName);
|
||||
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 {
|
||||
// process this file
|
||||
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
|
||||
* @param argc the number of arguments
|
||||
|
@ -248,18 +292,8 @@ int ipfs_import_files(int argc, char** argv) {
|
|||
struct Node* directory_entry = NULL;
|
||||
retVal = ipfs_import_file(current->file_name, &directory_entry, fs_repo);
|
||||
|
||||
// give some results to the user
|
||||
int buffer_len = 100;
|
||||
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_import_print_node_results(directory_entry, current->file_name);
|
||||
// cleanup
|
||||
ipfs_node_free(directory_entry);
|
||||
current = current->next;
|
||||
}
|
||||
|
@ -276,3 +310,4 @@ int ipfs_import_files(int argc, char** argv) {
|
|||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -127,12 +127,21 @@ int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struc
|
|||
* Node Functions
|
||||
*===================================================================================*/
|
||||
|
||||
/*ipfs_node_new
|
||||
/****
|
||||
* 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);
|
||||
|
||||
/***
|
||||
* 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
|
||||
* @param node the node to work with
|
||||
|
|
|
@ -8,6 +8,18 @@
|
|||
#include <string.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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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 */
|
||||
|
|
|
@ -356,6 +356,35 @@ int ipfs_node_new(struct Node** node)
|
|||
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
|
||||
* @param node the node to be modified
|
||||
|
|
54
os/utils.c
54
os/utils.c
|
@ -2,9 +2,11 @@
|
|||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
|
||||
/**
|
||||
* get an environment varible from the os
|
||||
|
@ -56,6 +58,58 @@ int os_utils_directory_exists(const char* directory_name) {
|
|||
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 result = access(path, W_OK);
|
||||
return result == 0;
|
||||
|
|
Loading…
Reference in a new issue