ipfs name command line options processing

yamux
jmjatlanta 2017-09-21 07:51:18 -05:00
parent a907f1dd2d
commit 2051f7714a
18 changed files with 278 additions and 53 deletions

View File

@ -1,5 +1,23 @@
all:
CC = gcc
CFLAGS = -O0 -I../include -I../../c-libp2p/include -I../../c-multiaddr/include -I../../c-protobuf -Wall
ifdef DEBUG
CFLAGS += -g3
endif
LFLAGS =
DEPS =
OBJS = cli.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
ipfs: $(OBJS)
$(CC) -o $@ $^ $(LFLAGS)
all: $(OBJS)
cd ipfs; make all;
clean:
rm -f *.o
cd ipfs; make clean;

26
cmd/cli.c Normal file
View File

@ -0,0 +1,26 @@
#include <stdlib.h>
#include "ipfs/cmd/cli.h"
int cli_get_verb_index(struct CliArguments* args) {
return 0;
}
char* cli_get_config_dir(struct CliArguments* args) {
return NULL;
}
struct CliArguments* cli_arguments_new(int argc, char** argv) {
struct CliArguments* args = (struct CliArguments*) malloc(sizeof(struct CliArguments));
if (args != NULL) {
args->argc = argc;
args->argv = argv;
args->verb_index = cli_get_verb_index(args);
args->config_dir = cli_get_config_dir(args);
}
return args;
}
void cli_arguments_free(struct CliArguments* args) {
free(args);
}

View File

@ -1,5 +1,23 @@
#include <stdlib.h>
#include "libp2p/utils/logger.h"
#include "ipfs/commands/cli/parse.h"
int cli_parse(char** params, FILE* inStream, struct Command* cmd, struct Request* request) {
/***
* Parse command line arguments, and place them in a Command struct
* @param argc number of arguments
* @param argv arguments
* @param inStream an incoming stream (not implemented yet)
* @param cmd the Command struct to allocate
* @param request not sure what this is for yet
* @returns true(1) on success, false(0) otherwise
*/
int cli_parse(int argc, char** argv, FILE* inStream, struct Command** cmd, struct Request* request) {
*cmd = (struct Command*) malloc(sizeof(struct Command));
if (*cmd == NULL) {
libp2p_logger_error("parse", "Unable to allocate memory for the command structure.\n");
return 0;
}
return 0;
}

View File

@ -95,7 +95,7 @@ int ipfs_node_online_new(pthread_t *pth_scope, const char* repo_path, struct Ipf
* @param node the completed IpfsNode struct
* @returns true(1) on success
*/
int ipfs_node_offline_new(pthread_t *pth_scope, const char* repo_path, struct IpfsNode** node) {
int ipfs_node_offline_new(const char* repo_path, struct IpfsNode** node) {
struct FSRepo* fs_repo = NULL;
*node = (struct IpfsNode*)malloc(sizeof(struct IpfsNode));
@ -112,13 +112,13 @@ int ipfs_node_offline_new(pthread_t *pth_scope, const char* repo_path, struct Ip
// build the struct
if (!ipfs_repo_fsrepo_new(repo_path, NULL, &fs_repo)) {
ipfs_node_free(pth_scope, local_node);
ipfs_node_free(NULL, local_node);
*node = NULL;
return 0;
}
// open the repo
if (!ipfs_repo_fsrepo_open(fs_repo)) {
ipfs_node_free(pth_scope, local_node);
ipfs_node_free(NULL, local_node);
*node = NULL;
return 0;
}
@ -147,7 +147,8 @@ int ipfs_node_offline_new(pthread_t *pth_scope, const char* repo_path, struct Ip
*/
int ipfs_node_free(pthread_t *pth_scope, struct IpfsNode* node) {
if (node != NULL) {
api_stop(pth_scope);
if (pth_scope != NULL)
api_stop(pth_scope);
if (node->exchange != NULL) {
node->exchange->Close(node->exchange);
}

View File

@ -266,14 +266,13 @@ int ipfs_exporter_object_cat_to_file(struct IpfsNode *local_node, unsigned char*
int ipfs_exporter_object_cat(int argc, char** argv) {
struct IpfsNode *local_node = NULL;
char* repo_dir = NULL;
pthread_t api_pth = 0;
if (!ipfs_repo_get_directory(argc, argv, &repo_dir)) {
fprintf(stderr, "Unable to open repo: %s\n", repo_dir);
return 0;
}
if (!ipfs_node_offline_new(&api_pth, repo_dir, &local_node))
if (!ipfs_node_offline_new(repo_dir, &local_node))
return 0;
if (local_node->mode == MODE_API_AVAILABLE) {

19
include/ipfs/cmd/cli.h Normal file
View File

@ -0,0 +1,19 @@
#pragma once
/**
* Helps parse the command line.
*/
/**
* A structure to hold the command line arguments
*/
struct CliArguments {
int argc;
char** argv;
int verb_index;
char* config_dir;
};
struct CliArguments* cli_arguments_new(int argc, char** argv);
void cli_arguments_free(struct CliArguments* args);

View File

@ -20,4 +20,12 @@ int ipfs_cmd_ipfs_init_command_new(struct Command* command);
*/
int ipfs_cmd_ipfs_init_command_free(struct Command* command);
/***
* Parse the command line
* @param argc the number of arguments
* @param argv the actual arguments
* @returns a command structure
*/
struct Command* ipfs_cmd_parse_command_line(int argc, char** argv);
#endif

View File

@ -16,7 +16,7 @@
* @param request the end result, something that can be passed on that actually does something
* @returns 0 if something bad happens, otherwise 1
*/
int cli_parse(char** params, FILE* inStream, struct Command* cmd, struct Request* request);
int cli_parse(int argc, char** params, FILE* inStream, struct Command** cmd, struct Request* request);
int cli_parse_opts(char** params, struct Command* cmd, char* path, char** stringVals);

View File

@ -1,5 +1,6 @@
#pragma once
#include <pthread.h>
#include "libp2p/peer/peerstore.h"
#include "libp2p/peer/providerstore.h"
#include "ipfs/blocks/blockstore.h"
@ -55,7 +56,7 @@ int ipfs_node_online_new(pthread_t *pth_scope, const char* repo_path, struct Ipf
* @param node the completed IpfsNode struct
* @returns true(1) on success
*/
int ipfs_node_offline_new(pthread_t *pth_scope, const char* repo_path, struct IpfsNode** node);
int ipfs_node_offline_new(const char* repo_path, struct IpfsNode** node);
/***
* Free resources from the creation of an IpfsNode

View File

@ -0,0 +1,11 @@
#pragma once
#include "ipfs/cmd/cli.h"
/**
* We received a cli command "ipfs name". Do the right thing.
* @param argc number of arguments on the command line
* @param argv actual command line arguments
* @returns true(1) on success, false(0) otherwise
*/
int ipfs_name(struct CliArguments* args);

View File

@ -6,6 +6,7 @@ OBJS = main.o \
../blocks/block.o ../blocks/blockstore.o \
../cid/cid.o \
../cmd/ipfs/init.o \
../cmd/*.o \
../commands/argument.o ../commands/command_option.o ../commands/command.o ../commands/cli/parse.o \
../core/*.o \
../datastore/ds_helper.o \

View File

@ -7,6 +7,8 @@
#include "ipfs/importer/exporter.h"
#include "ipfs/dnslink/dnslink.h"
#include "ipfs/core/daemon.h"
#include "ipfs/cmd/cli.h"
#include "ipfs/namesys/name.h"
#ifdef __MINGW32__
void bzero(void *s, size_t n)
@ -59,39 +61,84 @@ void strip_quotes(int argc, char** argv) {
#define DAEMON 6
#define PING 7
#define GET 8
#define NAME 9
/**
* Find out if this command line argument is part of a switch
* @param argc the number of arguments
* @param argv the arguments
* @param index the argument to look at
* @returns 0 if not a switch, 1 if it is a regular switch, 2 if the next parameter is also part of the switch
*/
int is_switch(int argc, char** argv, int index) {
char* to_test = argv[index];
if (to_test[0] == '-') {
if (strcmp(to_test, "-c") == 0 || strcmp(to_test, "--config") == 0) {
return 2;
}
return 1;
}
return 0;
}
/**
* Find the command line piece that will actually do something
* @param argc the number of command line arguments
* @param argv the actual command line arguments
* @returns the index of the item that does something, or false(0)
*/
int get_cli_verb(int argc, char** argv) {
for(int i = 1; i < argc; i++) {
int advance_by_more_than_one = is_switch(argc, argv, i);
if (advance_by_more_than_one == 0) {
// this is the verb
return i;
} else {
if (advance_by_more_than_one == 2) {
// skip the next one
i++;
}
}
}
return 0;
}
/***
* Basic parsing of command line arguments to figure out where the user wants to go
*/
int parse_arguments(int argc, char** argv) {
if (argc == 1) {
printf("No parameters passed.\n");
int index = get_cli_verb(argc, argv);
if (argc == 1 || index == 0) {
libp2p_logger_error("main", "No parameters passed.\n");
return 0;
}
if (strcmp("init", argv[1]) == 0) {
if (strcmp("init", argv[index]) == 0) {
return INIT;
}
if (strcmp("add", argv[1]) == 0) {
if (strcmp("add", argv[index]) == 0) {
return ADD;
}
if (strcmp("object", argv[1]) == 0 && argc > 2 && strcmp("get", argv[2]) == 0) {
if (strcmp("object", argv[index]) == 0 && argc > 2 && strcmp("get", argv[index+1]) == 0) {
return OBJECT_GET;
}
if (strcmp("cat", argv[1]) == 0) {
if (strcmp("cat", argv[index]) == 0) {
return CAT;
}
if (strcmp("dns", argv[1]) == 0) {
if (strcmp("dns", argv[index]) == 0) {
return DNS;
}
if (strcmp("daemon", argv[1]) == 0) {
if (strcmp("daemon", argv[index]) == 0) {
return DAEMON;
}
if (strcmp("ping", argv[1]) == 0) {
if (strcmp("ping", argv[index]) == 0) {
return PING;
}
if (strcmp("get", argv[1]) == 0) {
if (strcmp("get", argv[index]) == 0) {
return GET;
}
if (strcmp("name", argv[index]) == 0) {
return NAME;
}
return -1;
}
@ -111,32 +158,44 @@ int main(int argc, char** argv) {
libp2p_logger_add_class("lmdb_datastore");
strip_quotes(argc, argv);
int retVal = parse_arguments(argc, argv);
switch (retVal) {
case (INIT):
return ipfs_repo_init(argc, argv);
break;
case (ADD):
ipfs_import_files(argc, argv);
break;
case (OBJECT_GET):
ipfs_exporter_object_get(argc, argv);
break;
case(GET):
//ipfs_exporter_get(argc, argv);
//break;
case (CAT):
ipfs_exporter_object_cat(argc, argv);
break;
case (DNS):
ipfs_dns(argc, argv);
break;
case (DAEMON):
ipfs_daemon(argc, argv);
break;
case (PING):
ipfs_ping(argc, argv);
break;
// CliArguments is the new way to do it. Eventually, all will use this structure
struct CliArguments* args = cli_arguments_new(argc, argv);
if (args != NULL) {
// until then, use the old way
int retVal = parse_arguments(argc, argv);
switch (retVal) {
case (INIT):
return ipfs_repo_init(argc, argv);
break;
case (ADD):
ipfs_import_files(argc, argv);
break;
case (OBJECT_GET):
ipfs_exporter_object_get(argc, argv);
break;
case(GET):
//ipfs_exporter_get(argc, argv);
//break;
case (CAT):
ipfs_exporter_object_cat(argc, argv);
break;
case (DNS):
ipfs_dns(argc, argv);
break;
case (DAEMON):
ipfs_daemon(argc, argv);
break;
case (PING):
ipfs_ping(argc, argv);
break;
case (NAME):
ipfs_name(args);
break;
default:
libp2p_logger_error("main", "Invalid command line arguments.\n");
break;
}
cli_arguments_free(args);
}
libp2p_logger_free();
}

View File

@ -7,7 +7,7 @@ endif
LFLAGS =
DEPS =
OBJS = base.o dns.o isdomain.o namesys.o proquint.o publisher.o pb.o
OBJS = base.o dns.o isdomain.o namesys.o proquint.o publisher.o pb.o name.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)

65
namesys/name.c Normal file
View File

@ -0,0 +1,65 @@
/**
* Handles the command line options for "ipfs name"
*/
#include <stdlib.h>
#include "libp2p/utils/logger.h"
#include "ipfs/core/ipfs_node.h"
#include "ipfs/cmd/cli.h"
/***
* Publish IPNS name
*/
int ipfs_name_publish(struct IpfsNode* local_node, char* name) {
// call api
return 0;
}
int ipfs_name_resolve(struct IpfsNode* local_node, char* name) {
// ask api
return 0;
}
/**
* We received a cli command "ipfs name". Do the right thing.
* @param argc number of arguments on the command line
* @param argv actual command line arguments
* @returns true(1) on success, false(0) otherwise
*/
int ipfs_name(struct CliArguments* args) {
int retVal = 0;
struct IpfsNode* client_node = NULL;
if (args->argc < (args->verb_index + 2)) {
libp2p_logger_error("name", "Not enough command line arguments. Should be \"name resolve\" or \"name publish\".\n");
goto exit;
}
char* which = args->argv[args->verb_index+1];
char* path = args->argv[args->verb_index+2];
// make sure API is running
if (!ipfs_node_offline_new(args->config_dir, &client_node)) {
libp2p_logger_error("name", "Unable to create offline node.\n");
goto exit;
}
if (client_node->mode != MODE_API_AVAILABLE) {
libp2p_logger_error("name", "API must be running.\n");
goto exit;
}
// determine what we're doing
if (strcmp(which, "publish") == 0) {
retVal = ipfs_name_publish(client_node, path);
} else if (strcmp(which, "resolve") == 0) {
retVal = ipfs_name_resolve(client_node, path);
} else {
libp2p_logger_error("name", "Nothing found on command line. Should be \"name resolve\" or \"name publish\".\n");
goto exit;
}
exit:
// shut everything down
ipfs_node_free(NULL, client_node);
return retVal;
}

View File

@ -11,7 +11,6 @@ int test_core_api_startup_shutdown() {
char* repo_path = "/tmp/ipfs_1/.ipfs";
char* peer_id = NULL;
int retVal = 0;
pthread_t api_pth;
if (!drop_and_build_repository(repo_path, 4001, NULL, &peer_id))
goto exit;
@ -21,7 +20,7 @@ int test_core_api_startup_shutdown() {
sleep(3);
struct IpfsNode* client_node = NULL;
if (!ipfs_node_offline_new(&api_pth, repo_path, &client_node)) {
if (!ipfs_node_offline_new(repo_path, &client_node)) {
goto exit;
}
// test to see if it is working
@ -99,7 +98,7 @@ int test_core_api_object_cat() {
size_t bytes_written;
struct IpfsNode *local_node = NULL;
pthread_t api_pth = 0;
ipfs_node_offline_new(&api_pth, ipfs_path1, &local_node);
ipfs_node_offline_new(ipfs_path1, &local_node);
ipfs_import_file(NULL, filename, &node, local_node, &bytes_written, 0);
memset(hash, 0, 256);
ipfs_cid_hash_to_base58(node->hash, node->hash_size, (unsigned char*)hash, 256);

View File

@ -120,7 +120,7 @@ int test_journal_server_1() {
size_t bytes_written;
struct IpfsNode *local_node = NULL;
pthread_t api_pth = 0;
ipfs_node_offline_new(&api_pth, ipfs_path, &local_node);
ipfs_node_offline_new(ipfs_path, &local_node);
ipfs_import_file(NULL, filename, &node, local_node, &bytes_written, 0);
ipfs_node_free(&api_pth, local_node);
ipfs_hashtable_node_free(node);

View File

@ -14,7 +14,7 @@ int test_namesys_publisher_publish() {
pthread_t api_pth = 0;
// get a local node
if (!ipfs_node_offline_new(&api_pth, repo_path, &local_node)) {
if (!ipfs_node_offline_new(repo_path, &local_node)) {
libp2p_logger_error("test_publisher", "publish: Unable to open ipfs repository.\n");
goto exit;
}

View File

@ -157,7 +157,7 @@ int test_import_small_file() {
// get the repo
drop_and_build_repository(repo_path, 4001, NULL, NULL);
ipfs_node_offline_new(&api_pth, repo_path, &local_node);
ipfs_node_offline_new(repo_path, &local_node);
// write to ipfs
struct HashtableNode* write_node;