added first stupid example; will test it later;

v0.5.xx
Alexander Vdolainen 9 years ago
parent 11498689e3
commit 15fb867657

@ -1,18 +1,12 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
#if BUILD_EXAMPLES if BUILD_EXAMPLES
#EXAMPLES = examples EXAMPLES = examples
#else
#EXAMPLES =
#endif
if BUILD_TESTS
TESTS = tests
else else
TESTS = EXAMPLES =
endif endif
SUBDIRS = include lib man $(TESTS) SUBDIRS = include lib man $(EXAMPLES)
libsxmpdocdir = ${prefix}/doc/libsxmp libsxmpdocdir = ${prefix}/doc/libsxmp
libsxmpdoc_DATA = \ libsxmpdoc_DATA = \

@ -16,23 +16,14 @@ dnl *****************
dnl ***** options ***** dnl ***** options *****
dnl ***************** dnl *****************
#AC_ARG_ENABLE([build_examples], AC_ARG_ENABLE([build_examples],
# AS_HELP_STRING([--enable-build-examples], [Enable examples build])) AS_HELP_STRING([--enable-build-examples], [Enable examples build]))
#AS_IF([test "x$enable_build_examples" = "xyes"], [ AS_IF([test "x$enable_build_examples" = "xyes"], [
# AC_DEFINE([BUILD_EXAMPLES], 1, [build of examples enabled]) AC_DEFINE([BUILD_EXAMPLES], 1, [build of examples enabled])
#])
#AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_build_examples" = "xyes")
AC_ARG_ENABLE([build_tests],
AS_HELP_STRING([--enable-build-tests], [Enable build of tests]))
AS_IF([test "x$enable_build_tests" = "xyes"], [
AC_DEFINE([BUILD_TESTS], 1, [build of tests enabled])
]) ])
AM_CONDITIONAL(BUILD_TESTS, test "x$enable_build_tests" = "xyes") AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_build_examples" = "xyes")
PKG_CHECK_MODULES(OPENSSL, [openssl]) PKG_CHECK_MODULES(OPENSSL, [openssl])
@ -61,4 +52,4 @@ lib/libsxmp.pc
lib/Makefile lib/Makefile
include/Makefile include/Makefile
man/Makefile man/Makefile
tests/Makefile]) examples/Makefile])

@ -0,0 +1,2 @@
filelistc
filelistd

@ -0,0 +1,25 @@
## AUTOMAKE_OPTIONS = foreign
AM_CPPFLAGS = \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
-DCNFPATH=\""$(prefix)/etc"\" \
-I../include \
-I../lib
AM_CFLAGS = -Wall -g
# where to find libsxmp
libsxmp = ../lib/.libs/libsxmp.la
bin_PROGRAMS = filelistd filelistc
filelistd_SOURCES = filelistd.c
filelistd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsxmp) -lpthread
filelistc_SOURCES = filelistc.c
filelistc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsxmp) -lpthread

@ -38,6 +38,10 @@
#define DEFAULT_PORT 10240 #define DEFAULT_PORT 10240
#define READONLY_CHANNEL 8
#define WRITE_CHANNEL 16
#define CONTROL_CHANNEL 20
#define DEBUG #define DEBUG
#define FREE(x) { if (x) { free(x); x = NULL; } } #define FREE(x) { if (x) { free(x); x = NULL; } }
#define MAX_STREAMS INT_MAX #define MAX_STREAMS INT_MAX

@ -61,10 +61,386 @@
#include <errno.h> #include <errno.h>
#include "filelist.h" #include "filelist.h"
#include "../config.h"
#define FULL_PROGRAM_NAME "File lister client"
struct _remote_host {
char *root_x509;
char *user_x509;
char *hostname;
char *login;
char *password;
int port;
sxhub_t *hub;
sxlink_t *link;
};
struct _icmd {
int id;
int opt;
char *cmdname;
int (*__fu)(FILE *, struct _remote_host *, const char *);
};
/* supported commands */
enum commands {
__LISTDIR = 0,
};
static int __remote_ls(FILE *, struct _remote_host *, const char *);
struct _icmd _tool[] = {
{ .id = __LISTDIR, .opt = 0, .cmdname = "ls", .__fu = __remote_ls },
{ .id = 0, .opt = 0, .cmdname = NULL, .__fu = NULL },
};
/*
* This function might be used to check supported RPC calls
* i.e. for each channel type id this callback is called.
* Whereas the place to check it with ID and description.
* Should return SXE_SUCCESS if supported.
*/
static int __rpcscheck_onclient(sxlink_t *l, int ch_tid, char *description)
{
return SXE_SUCCESS;
}
/* supplemetary functions to make code more readable */
static int __close_dir_stream(sxchnl_t *c, int sid)
{
int r = SXE_SUCCESS;
char *remote_rpc;
size_t remote_rpc_len;
sxmsg_t *msg = NULL;
remote_rpc_len = strlen("dir-close") + sizeof(char)*16;
if(!(remote_rpc = malloc(remote_rpc_len))) return ENOMEM;
else remote_rpc_len = snprintf(remote_rpc, remote_rpc_len, "(dir-close %d)", sid);
r = sxmsg_send(c, remote_rpc, remote_rpc_len, &msg);
if(r == SXE_RAPIDMSG) sxmsg_clean(msg);
else if(r == SXE_REPLYREQ) r = sxmsg_return(msg, SXE_SUCCESS);
return r;
}
/* our commands or tools implementation */
static int __remote_ls(FILE *fso, struct _remote_host *rh, const char *opts)
{
char *remote_rpc;
size_t remote_rpc_len;
sxmsg_t *msg = NULL;
sxchnl_t *rpc_channel = NULL;
sexp_t *sx, *isx, *iisx;
char *remote_reply = NULL, *dname, *dtype;
int rrc = 0, stream_id = 0, i, ii;
/* ok determine the lenght */
remote_rpc_len = strlen("dir-open") + 12*sizeof(char) +
(opts ? strlen ("./") : strlen(opts));
if(!(remote_rpc = malloc(remote_rpc_len))) return ENOMEM;
else remote_rpc_len = snprintf(remote_rpc, remote_rpc_len,
"(dir-open \"%s\")", opts ? "./" : opts);
/* firstly open the required channel with required type */
if(!(rpc_channel = sxchannel_open(rh->link, READONLY_CHANNEL))) {
rrc = errno;
goto __fini;
}
rrc = sxmsg_send(rpc_channel, remote_rpc, remote_rpc_len, &msg);
if(rrc == SXE_RAPIDMSG || rrc == SXE_REPLYREQ) {
remote_reply = strdup(sxmsg_payload(msg));
if(rrc == SXE_RAPIDMSG) sxmsg_clean(msg);
else rrc = sxmsg_return(msg, SXE_SUCCESS);
}
if(!remote_reply && (rrc != 0 || rrc != SXE_SUCCESS)) goto __fini;
else sx = parse_sexp(remote_reply, strlen(remote_reply));
if(!sx) { rrc = EINVAL; goto __fini; }
/* ok, now we will take a pass with our received S expression */
rrc = EINVAL;
SEXP_ITERATE_LIST(sx, isx, i) {
if(isx->ty == SEXP_LIST) stream_id = -1;
if(!i && strcmp(isx->val, "dir-stream")) stream_id = -1;
if(i == 1 && !stream_id) stream_id = atoi(isx->val);
}
/* free all the stuff */
destroy_sexp(sx);
free(remote_reply); remote_reply = NULL;
if(stream_id < 0) goto __fini;
else rrc = SXE_SUCCESS;
free(remote_rpc);
/* now we're ready to read contents from the remote host */
remote_rpc_len = strlen("dir-read") + sizeof(char)*32;
if(!(remote_rpc = malloc(remote_rpc_len))) { rrc = ENOMEM; goto __fini; }
else remote_rpc_len = snprintf(remote_rpc, remote_rpc_len, "(dir-read %d)", stream_id);
/* print header */
fprintf(fso, "%-24s | %-12s\n", "Name", "Type");
fprintf(fso, "---------------------------------------\n");
while(1) {
rrc = sxmsg_send(rpc_channel, remote_rpc, remote_rpc_len, &msg);
if(rrc == SXE_RAPIDMSG || rrc == SXE_REPLYREQ) {
remote_reply = strdup(sxmsg_payload(msg));
if(rrc == SXE_RAPIDMSG) sxmsg_clean(msg);
else rrc = sxmsg_return(msg, SXE_SUCCESS);
} else goto __fini;
if(!remote_reply) goto __fini;
else if(!(sx = parse_sexp(remote_reply, strlen(remote_reply)))) {
rrc = ENOMEM;
goto __fini;
}
rrc = EINVAL;
SEXP_ITERATE_LIST(sx, isx, i) {
if(!i && isx->ty == SEXP_LIST) { rrc = EINVAL; goto __fini; }
if(!i && !strcmp(isx->val, "dir-end")) {
rrc = __close_dir_stream(rpc_channel, stream_id);
goto __fini;
}
if(i && isx->ty != SEXP_LIST) { rrc = EINVAL; goto __fini; }
else if(i) {
SEXP_ITERATE_LIST(isx, iisx, ii) {
if(!ii) dname = iisx->val;
else dtype = iisx->val;
}
fprintf(fso, "%-24s | %-12s\n", dname, dtype);
}
}
/* free it */
destroy_sexp(sx);
free(remote_reply); remote_reply = NULL;
}
__fini:
if(remote_reply) free(remote_reply);
if(remote_rpc) free(remote_rpc);
i = SXE_SUCCESS;
if(rpc_channel) i = sxchannel_close(rpc_channel);
if(rrc == SXE_SUCCESS && i == SXE_SUCCESS) rrc = 0;
return rrc;
}
static int __remote_host_connect(struct _remote_host *rh)
{
int r = 0;
sxhub_set_channelcall(rh->hub, __rpcscheck_onclient);
/* here we go, connect to the hist i.e. create a link to it */
rh->link = sxlink_connect(rh->hub, rh->hostname, rh->port, rh->user_x509,
rh->login, rh->password);
if(!rh->link) r = errno;
return r;
}
static void __help_print(FILE *fso, const char *fmtname)
{
fprintf(fso, "\n%s\n\n", FULL_PROGRAM_NAME);
/* usage options */
fprintf(fso, "Usage:\n");
fprintf(fso, "\t%s -r | --root-x509 <path> -u | --user-x509 <path> -H | --hostname <ip or hostname>"
" -l | --login <login> -P | --password <password> -c | --command <command>"
" [-o | --command-options <options>] [-p | --port <port>]\n", fmtname);
/* defaults */
fprintf(fso, "\t%s -h | --help\n", fmtname);
fprintf(fso, "\t%s -v | --version\n", fmtname);
/* options description */
fprintf(fso, "\nOptions:\n");
fprintf(fso, "\t%-33s Set pathname of the remote root X.509 public certificate.\n", "-r | --root-x509 <path>");
fprintf(fso, "\t%-33s Set pathname of the user X.509 public and private certificate.\n",
"-u | --user-x509 <path>");
fprintf(fso, "\t%-33s Hostname or IP address of the remote host.\n", "-H | --hostname <ip or hostname>");
fprintf(fso, "\t%-33s Set remote login name.\n", "-l | --login <login>");
fprintf(fso, "\t%-33s Set remote user password.\n", "-P | --password <password>");
fprintf(fso, "\t%-33s Command to run on the remote host.\n", "-c | --command <command>");
fprintf(fso, "\t%-33s Options for a command to run on the remote host [default: NULL].\n",
"-o | --command-options <options>");
fprintf(fso, "\t%-33s Remote host listening port number [default: %d].\n",
"-p | --port <port>", DEFAULT_PORT);
fprintf(fso, "\t%-33s Show help screen.\n", "-h | --help");
fprintf(fso, "\t%-33s Print version information.\n", "-v | --version");
return;
}
static void __version_print(FILE *fso)
{
fprintf(fso, "\nFile list example client.\n");
fprintf(fso, "Examples bundle for %s %s.\n", PACKAGE_NAME, PACKAGE_VERSION);
return;
}
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int opt; char *rootca, *cert, *host, *cmd;
char *login, *password, *options;
int port = DEFAULT_PORT, opt, i = 0;
int (*toolfunction)(FILE *, struct _remote_host *, const char *) = NULL;
struct _remote_host *rh = malloc(sizeof(struct _remote_host));
sxhub_t *lhub;
if(!rh) return ENOMEM;
else memset(rh, 0, sizeof(struct _remote_host));
rootca = cert = host = cmd = NULL;
login = password = options = NULL;
while(1) {
int option_index = 0;
static struct option long_options[] = {
/* These options a generic ones. */
{"help", no_argument, NULL, 'h'}, /* print out help and version info */
{"version", no_argument, NULL, 'v'}, /* just out a version info */
/* The following options about settings . */
{"root-x509", required_argument, NULL, 'r'},
{"user-x509", required_argument, NULL, 'u'},
{"hostname", required_argument, NULL, 'H'},
{"port", required_argument, NULL, 'p'},
{"login", required_argument, NULL, 'l'},
{"password", required_argument, NULL, 'P'},
{"command", required_argument, NULL, 'c'},
{"command-options", required_argument, NULL, 'o'},
{ NULL, 0, NULL, 0 },
};
if((opt = getopt_long(argc, argv, "hvr:u:H:p:l:P:c:o:", long_options,
&option_index)) == -1) break;
switch(opt) {
case 'h':
__help_print(stdout, argv[0]);
return 0;
break;
case 'v':
__version_print(stdout);
return 0; return 0;
break;
case 'r':
if(!(rootca = strdup(optarg))) return ENOMEM;
break;
case 'u':
if(!(cert = strdup(optarg))) return ENOMEM;
break;
case 'H':
if(!(host = strdup(optarg))) return ENOMEM;
break;
case 'l':
if(!(login = strdup(optarg))) return ENOMEM;
break;
case 'P':
if(!(password = strdup(optarg))) return ENOMEM;
break;
case 'c':
if(!(cmd = strdup(optarg))) return ENOMEM;
break;
case 'o':
if(!(options = strdup(optarg))) return ENOMEM;
break;
case 'p':
port = atoi(optarg);
break;
}
}
/* ok validate all before doing any stuff */
if(!rootca || !cert) {
fprintf(stderr, "One or more x.509 certificates files not pointed.\n");
__help_print(stderr, argv[0]);
return EINVAL;
}
if(!login || !password) {
fprintf(stderr, "Login or password not pointed.\n");
__help_print(stderr, argv[0]);
return EINVAL;
}
if(port <= 0) {
fprintf(stderr, "Port number has invalid value.\n");
__help_print(stderr, argv[0]);
return EINVAL;
}
/* ok, check up for the command */
if(!cmd) {
fprintf(stderr, "No command given.\n");
__help_print(stderr, argv[0]);
return EINVAL;
}
/* try to lookup it */
while(_tool[i].cmdname != NULL) {
if(!strcmp(_tool[i].cmdname, cmd)) {
if(_tool[i].opt && !options) {
fprintf(stderr, "Command %s required options.\n", cmd);
__help_print(stderr, argv[0]);
return EINVAL;
}
toolfunction = _tool[i].__fu;
}
}
if(!toolfunction) {
fprintf(stderr, "No such function `%s' exist.\n", cmd);
__help_print(stderr, argv[0]);
return EINVAL;
}
/* initialize sxmp first */
sxmp_init(); /* init library */
lhub = sxhub_create(); /* create sxhub for link creation */
if(!lhub) return ENOMEM;
i = sxhub_setsslserts(lhub, rootca, cert, cert);
if(i) return i;
/* ok setup our structure */
rh->port = port;
rh->root_x509 = rootca;
rh->user_x509 = cert;
rh->hostname = host;
rh->login = login;
rh->password = password;
rh->hub = lhub;
i = __remote_host_connect(rh);
if(i) {
fprintf(stderr, "Failed to create link to %s@%s:%d with %d.\n", rh->login, rh->hostname,
rh->port, i);
} else {
i = toolfunction(stdout, rh, options);
if(i) fprintf(stderr, "Failed to run RPC on %s@%s:%d with %d.\n", rh->login, rh->hostname,
rh->port, i);
sxlink_close(rh->link); /* don't forget to do this */
}
/* free all stuff */
if(rh->root_x509) free(rh->root_x509);
if(rh->user_x509) free(rh->user_x509);
if(rh->hostname) free(rh->hostname);
if(rh->password) free(rh->password);
if(rh->login) free(rh->login);
free(rh);
if(lhub) sxhub_destroy(lhub);
return i;
} }

@ -169,7 +169,7 @@ static int __validate_sslpem(sxlink_t *l)
* We don't overview this tuff here, just * We don't overview this tuff here, just
* always allow. * always allow.
*/ */
static int __secure_check(conn_t *co) static int __secure_check(sxlink_t *l)
{ {
return SXE_SUCCESS; return SXE_SUCCESS;
} }
@ -385,8 +385,8 @@ int main(int argc, char **argv)
return opt; return opt;
} }
/* we will add one channel with type id 12 "Demo rpc list" */ /* we will add one channel with type id READONLY_CHANNEL for read only operations */
opt = sxmp_rpclist_add(fulist, 12, "Demo RPC list", NULL); opt = sxmp_rpclist_add(fulist, READONLY_CHANNEL, "Read only operations", NULL);
if(opt) { if(opt) {
fprintf(stderr, "Failed to add typed RPC channel\n Failure.\n"); fprintf(stderr, "Failed to add typed RPC channel\n Failure.\n");
return opt; return opt;
@ -398,15 +398,15 @@ int main(int argc, char **argv)
} }
/* ok, let's add stream functions */ /* ok, let's add stream functions */
opt = sxmp_rpclist_add_function(fulist, 12, "dir-open", __dir_open); opt = sxmp_rpclist_add_function(fulist, READONLY_CHANNEL, "dir-open", __dir_open);
if(opt) { if(opt) {
__fail: __fail:
fprintf(stderr, "Failed to add functions to typed RPC channel\n Failure.\n"); fprintf(stderr, "Failed to add functions to typed RPC channel\n Failure.\n");
return opt; return opt;
} }
opt = sxmp_rpclist_add_function(fulist, 12, "dir-read", __dir_read); opt = sxmp_rpclist_add_function(fulist, READONLY_CHANNEL, "dir-read", __dir_read);
if(opt) goto __fail; if(opt) goto __fail;
opt = sxmp_rpclist_add_function(fulist, 12, "dir-close", __dir_close); opt = sxmp_rpclist_add_function(fulist, READONLY_CHANNEL, "dir-close", __dir_close);
if(opt) goto __fail; if(opt) goto __fail;
/* ok, setup it */ /* ok, setup it */

@ -1,46 +0,0 @@
## AUTOMAKE_OPTIONS = foreign
AM_CPPFLAGS = \
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
-DCNFPATH=\""$(prefix)/etc"\" \
-I../include \
-I../lib
AM_CFLAGS = -Wall -g
# where to find libsntl
libsntl = ../lib/.libs/libsntl.la
if !COND_WIN32
bin_PROGRAMS = lv2sd lv2sc lv2ftpd lv2ftpc
lv2sd_SOURCES = lv2sd.c
lv2sd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl) -lpthread
lv2sc_SOURCES = lv2sc.c
lv2sc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl) -lpthread
lv2ftpd_SOURCES = lv2ftpd.c
lv2ftpd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl) -lpthread
lv2ftpc_SOURCES = lv2ftpc.c
lv2ftpc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl) -lpthread
else COND_WIN32
bin_PROGRAMS = lv2sc
lv2sc_SOURCES = lv2sc.c
lv2sc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
$(LIBUUID_LIBS) $(libsntl) -lws2_32
endif COND_WIN32

@ -1,30 +0,0 @@
1. lv2ftp isn's serious, just a test and benchmark of the sntllv2
2. there are few stages:
2.1 Simple v.1
This protocol is enough to donwload a directory subtree with files.
2.1.1 Directory workout
* Open directory stream: (dir-open "<dir-name>")
* Return: error, or rapidly replies with (dir-stream <id>)
* Read directory entry: (dir-read <id>)
* Return: error, or rapidly replies with the following:
* (dir-end <id>)
* (dir-entry "<filename>" "<filetype>"), where filetype the following:
* regular - regular file
* directory - directory
* block - block device
* char - char device
* fifo - named pipe
* link - symbolic link
* socket - socket
* unknown - unknown file type
* Close directory entry: (dir-close <id>)
* Return: error or SNE_SUCCESS
2.1.2 File workout
* Open file: (file-open "<file-name>")
* Return: error, or rapidly replies with (file-id <id>)
* Get simple stat: (file-stat <id>)
* Return error, or rapidle replies with (file-stat <id> <size>)
* Read file data: (file-read <id> <offset>)
* Return error, or rapidly replies with 30k(raw data, in base64 it will be more) (file-data <id> <offset> "<B64encoded data>")
* Close file: (file-close <id>)
* Return error or SNE_SUCCESS

@ -1,352 +0,0 @@
#include <stdio.h>
#define __USE_GNU
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h>
#include <pthread.h>
#include <stdint.h>
#include <getopt.h>
#include <errno.h>
#include <assert.h>
#include <time.h>
#ifdef WIN32
#include <Winsock2.h>
#include <signal.h>
#else
#include <sys/select.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <netdb.h>
#include <unistd.h>
#include <uuid/uuid.h>
#include <execinfo.h>
#include <netinet/in.h>
#endif
#include <tdata/usrtc.h>
#include <sexpr/sexp.h>
#include <sntl/sntllv2.h>
#include <sntl/limits.h>
#define DEBUG
#define FREE(x) { if (x) { free(x); x = NULL; } }
/* define a little bit */
#define DEFAULT_PORT 13133
#define CHANNEL_COUNT 200
#define CLIENT_COUNT 256
#define MESSAGES_PER_SESSION 10000
#define ITERATION_COUNT 1000
#define FAILS_ONLY
struct testdata {
int uc;
pthread_mutex_t ulock;
conn_t *co;
};
static int __init_testdata(struct testdata *t, conn_t *co)
{
t->uc = 0;
pthread_mutex_init(&t->ulock, NULL);
t->co = co;
return 0;
}
static void __wait_completion(struct testdata *t)
{
pthread_mutex_lock(&t->ulock);
if(t->uc) {
pthread_mutex_lock(&t->ulock);
}
return;
}
static int __set_typed_list_callback(conn_t *co, int ch, char *desc)
{
printf("allowed channel %d (%s)\n", ch, desc);
return SNE_SUCCESS;
}
static void *__addsthrd(void *a)
{
struct testdata *t = a;
conn_t *co = t->co;
chnl_t *mch;
sxmsg_t *msg;
char mmbuf[1024];
size_t ln;
int mr, i;
pthread_mutex_lock(&t->ulock);
t->uc++;
pthread_mutex_unlock(&t->ulock);
/* here we go */
mch = sxchannel_open(co, 12);
if(!mch) {
fprintf(stderr, "Failed to openchannel with %d\n", errno);
goto __fini;
}
for(i = 0; i < MESSAGES_PER_SESSION; i++) {
ln = snprintf(mmbuf, 1024, "(ar-add (10 10))");
mr = sxmsg_send(mch, mmbuf, ln, &msg);
switch(mr) {
case SNE_RAPIDMSG:
//fprintf(stdout, "Rapidly replied: %s\n", (char *)sxmsg_payload(msg));
sxmsg_clean(msg);
break;
case SNE_REPLYREQ:
if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n",
(char *)sxmsg_payload(msg));
mr = sxmsg_return(msg, SNE_SUCCESS);
fprintf(stderr, "mr = %d\n", mr);
break;
case SNE_SUCCESS:
fprintf(stdout, "Success.\n");
break;
default:
fprintf(stderr, "ERROR: %d\n", mr);
break;
}
}
sxchannel_close(mch);
__fini:
t->uc--;
if(t->uc <= 1) pthread_mutex_unlock(&t->ulock);
return NULL;
}
int msg_send(chnl_t *ch, const char *mmbuf, size_t buflen, sxmsg_t *msg, char **rs)
{
#ifdef DEBUG
printf("%s: got sx '%s'\n", __FUNCTION__, mmbuf);
#endif /* DEBUG */
int mr = sxmsg_send(ch, mmbuf, buflen, &msg);
switch(mr) {
case SNE_RAPIDMSG:
if (rs) *rs = strdup((char *)sxmsg_payload(msg));
fprintf(stdout, "Rapidly replied: '%s'\n", (char *)sxmsg_payload(msg));
sxmsg_clean(msg);
break;
case SNE_REPLYREQ:
if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n",
(char *)sxmsg_payload(msg));
mr = sxmsg_return(msg, SNE_SUCCESS);
fprintf(stderr, "mr = %d\n", mr);
break;
case SNE_SUCCESS:
fprintf(stdout, "Success.\n");
break;
default:
fprintf(stderr, "ERROR: %d\n", mr);
break;
}
#ifdef DEBUG
// printf("%s: got rs %d\n", __FUNCTION__, mr);
#endif /* DEBUG */
return mr;
}
int main(int argc, char **argv)
{
char *rootca = NULL, *cert = NULL;
int port = DEFAULT_PORT;
char *addr = NULL, *login = NULL, *password = NULL;
int opt;
conn_sys_t *ssys;
conn_t *co;
while((opt = getopt(argc, argv, "p:r:a:u:l:w:")) != -1) {
switch(opt) {
case 'p':
port = atoi(optarg);
break;
case 'r':
rootca = strdup(optarg);
break;
case 'a':
addr = strdup(optarg);
break;
case 'u':
cert = strdup(optarg);
break;
case 'l':
login = strdup(optarg);
break;
case 'w':
password = strdup(optarg);
break;
default:
fprintf(stderr, "usage: %s [-p <PORTNUM>] -r <PATH to Root CA> -a <Server ip address> -u <PATH"
" to SSL certificate> -l <User login> -w <User password>\n", argv[0]);
return EINVAL;
}
}
if(!rootca) {
fprintf(stderr, "Root CA not pointed.\n Failure.\n");
return EINVAL;
}
if(!addr) {
fprintf(stderr, "Server address not pointed.\n Failure.\n");
return EINVAL;
}
if(!cert) {
fprintf(stderr, "User certificate not pointed.\n Failure.\n");
return EINVAL;
}
if(!login) {
fprintf(stderr, "User login not pointed.\n Failure.\n");
return EINVAL;
}
if(!password) {
fprintf(stderr, "User password not pointed.\n Failure.\n");
return EINVAL;
}
sntl_init();
/* all is fine let's init connection subsystem */
ssys = connections_create();
if(!ssys) {
fprintf(stderr, "Subsystem init failed: %d\n", errno);
return errno;
}
/* set working certificates */
opt = connections_setsslserts(ssys, rootca, cert, cert);
if(opt) {
fprintf(stderr, "Subsystem init failed (set SSL x.509 pems): %d\n", opt);
return opt;
}
/* Tests */
struct timeval beg, end;
/* try to open connection */
connections_set_channelcall(ssys, __set_typed_list_callback);
gettimeofday(&beg, NULL);
co = connection_link(ssys, addr, port, cert, login, password);
if(!co) {
fprintf(stderr, "Failed to connection with %d\n", errno);
return errno;
}
gettimeofday(&end, NULL);
if((end.tv_sec - beg.tv_sec) > 0) {
printf("Seconds: %ld ", end.tv_sec - beg.tv_sec);
printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec));
} else printf("µS: %ld\n", end.tv_usec - beg.tv_usec);
/* ok now we should open a channel */
chnl_t *testchannel = sxchannel_open(co, 12);
if(!testchannel) {
fprintf(stderr, "Failed to openchannel with %d\n", errno);
return errno;
}
gettimeofday(&end, NULL);
if((end.tv_sec - beg.tv_sec) > 0) {
printf("Seconds: %ld ", end.tv_sec - beg.tv_sec);
printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec));
} else printf("µS: %ld\n", end.tv_usec - beg.tv_usec);
/* ok, send a message */
char mmbuf[1024];
char *s_ret = NULL;
sxmsg_t *msg = NULL;
size_t ln;
int mr, ee, stid;
sexp_t *sx_ret = NULL;
ln = snprintf(mmbuf, 1024, "(dir-open \".\")");
mr = msg_send(testchannel, mmbuf, ln, msg, &s_ret);
if (mr != SNE_RAPIDMSG) goto __finish;
sx_ret = parse_sexp(s_ret, strlen(s_ret));
FREE(s_ret);
if (!sx_ret || !sx_ret->list || strcmp(sx_ret->list->val, "dir-stream") ||
!sx_ret->list->next || !sx_ret->list->next->val)
goto __finish;
stid = atoi(sx_ret->list->next->val);
ln = snprintf(mmbuf, 1024, "(dir-read %d)", stid);
while (1) {
mr = msg_send(testchannel, mmbuf, ln, msg, &s_ret);
if (mr != SNE_RAPIDMSG) goto __finish;
sx_ret = parse_sexp(s_ret, strlen(s_ret));
if (!sx_ret || !sx_ret->list || !sx_ret->list->val)
goto __finish;
if (!strcmp(sx_ret->list->val, "dir-end")) {
ln = snprintf(mmbuf, 1024, "(dir-close %d)", stid);
mr = msg_send(testchannel, mmbuf, ln, msg, &s_ret);
break;
}
#ifdef DEBUG
printf("%s: '%s'\n", __FUNCTION__, s_ret);
#endif /* DEBUG */
FREE(s_ret);
}
// switch(mr) {
// case SNE_RAPIDMSG:
// fprintf(stdout, "Rapidly replied: %s\n", (char *)sxmsg_payload(msg));
// sxmsg_clean(msg);
// break;
// case SNE_REPLYREQ:
// if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n",
// (char *)sxmsg_payload(msg));
// mr = sxmsg_return(msg, SNE_SUCCESS);
// fprintf(stderr, "mr = %d\n", mr);
// break;
// case SNE_SUCCESS:
// fprintf(stdout, "Success.\n");
// break;
// default:
// fprintf(stderr, "ERROR: %d\n", mr);
// break;
// }
__finish:
ee = sxchannel_close(testchannel);
printf("ee = %d\n", ee);
gettimeofday(&end, NULL);
if((end.tv_sec - beg.tv_sec) > 0) {
printf("Seconds: %ld ", end.tv_sec - beg.tv_sec);
printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec));
} else printf("µS: %ld\n", end.tv_usec - beg.tv_usec);
// sleep(10);
// /* ok, now we need to create many threads */
// struct testdata trd;
// pthread_t thrd;
// int i;
// __init_testdata(&trd, co);
// for(i = 0; i < 256; i++) pthread_create(&thrd, NULL, __addsthrd, &trd);
// __wait_completion(&trd);
connection_close(co);
connections_destroy(ssys);
sntl_finalize();
return 0;
}
Loading…
Cancel
Save