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/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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
54
os/utils.c
54
os/utils.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue