From 0950618bacf1d04195733098a3f79a048276c4fb Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
Date: Mon, 28 Aug 2017 00:03:35 +0200
Subject: [PATCH] remoted & remotec: compilation, connection to remoted serv
---
pubsub/lib/pubsubd.c | 4 ++
remote/app/README.md | 3 +
remote/app/remotec.c | 40 ++++++-------
remote/app/remoted.c | 42 +++++++++++--
remote/lib/msg.c | 109 ++++++++++++++++++++++++++++++++++
remote/lib/msg.h | 20 +++++++
remote/lib/remote.h | 9 ---
remote/lib/remotec.c | 74 +++++++++++++++++++++++
remote/lib/remotec.h | 16 +++++
remote/lib/remoted.c | 138 +++++++++++++++++++++++++++++++++++++++++--
remote/lib/remoted.h | 7 ++-
11 files changed, 420 insertions(+), 42 deletions(-)
create mode 100644 remote/lib/msg.c
create mode 100644 remote/lib/msg.h
delete mode 100644 remote/lib/remote.h
create mode 100644 remote/lib/remotec.c
create mode 100644 remote/lib/remotec.h
diff --git a/pubsub/lib/pubsubd.c b/pubsub/lib/pubsubd.c
index 4d21856..62bfb45 100644
--- a/pubsub/lib/pubsubd.c
+++ b/pubsub/lib/pubsubd.c
@@ -55,6 +55,10 @@ void pubsubd_send (const struct array_proc *ap, const struct pubsub_msg * m)
// msg_free (&m_data);
// }
+/**
+ * new connection, once accepted the process is added to the array_proc
+ * structure to be checked periodically for new messages
+ */
void handle_new_connection (struct service *srv, struct array_proc *ap)
{
struct process *p = malloc(sizeof(struct process));
diff --git a/remote/app/README.md b/remote/app/README.md
index 551fdd2..f89adbf 100644
--- a/remote/app/README.md
+++ b/remote/app/README.md
@@ -4,6 +4,9 @@ This service creates a path on the relevent remote location, going through anyth
# TODO
+* authorizations
+* code the -d option
+
### authorizations
The idea is to have a simple configuration file for authentication of remote connections, such as:
diff --git a/remote/app/remotec.c b/remote/app/remotec.c
index 666f8fd..ff28d5e 100644
--- a/remote/app/remotec.c
+++ b/remote/app/remotec.c
@@ -1,9 +1,8 @@
-// int main(void) { return 0; }
-
#include "../../core/communication.h"
#include "../../core/error.h"
#include "../lib/remoted.h"
-#include "../lib/remote.h"
+#include "../lib/remotec.h"
+#include "../lib/msg.h"
#include
#include
@@ -31,8 +30,8 @@ void * listener (void *params)
// main loop
while (1) {
- struct remote_msg m;
- memset (&m, 0, sizeof (struct remote_msg));
+ struct remoted_msg m;
+ memset (&m, 0, sizeof (struct remoted_msg));
remote_msg_recv (srv, &m);
printf ("\r\033[31m>\033[00m %s\n", m.data);
@@ -55,31 +54,30 @@ void main_loop (int argc, char **argv, char **env
(void) argv;
(void) env;
-#if 0
struct service srv;
memset (&srv, 0, sizeof (struct service));
- remote_connection (argc, argv, env, &srv);
- printf ("connected\n");
+ remotec_connection (argc, argv, env, &srv);
+ log_debug ("remotec connected");
+ log_debug ("remotec main loop");
- printf ("main_loop\n");
-
- struct remote_msg msg;
- memset (&msg, 0, sizeof (struct remote_msg));
+ struct remoted_msg msg;
+ memset (&msg, 0, sizeof (struct remoted_msg));
+#if 0
// msg loop
for (;;) {
char buf[BUFSIZ];
memset (buf, 0, BUFSIZ);
- msg.datalen = /* TODO */0;
- msg.data = /* TODO */ NULL;
+ /* TODO */
+ msg.datalen = 5; // FIXME: take parameters into account
+ msg.data = malloc (msg.datalen);
memset (msg.data, 0, msg.datalen);
- strncpy ((char *) msg.data, /* TODO */NULL, msg.datalen);
- msg.data[msg.datalen -1] = '\0';
+ strncpy ((char *) msg.data, "salut", msg.datalen);
/* TODO */
- remote_msg_send (&srv, &msg);
+ remotec_msg_send (&srv, &msg);
free (msg.data);
msg.data = NULL;
msg.datalen = 0;
@@ -87,11 +85,11 @@ void main_loop (int argc, char **argv, char **env
// free everything
remote_msg_free (&msg);
-
- printf ("disconnection...\n");
- // disconnect from the server
- remote_disconnect (&srv);
#endif
+
+ log_debug ("remotec disconnection...");
+ // disconnect from the server
+ remotec_disconnection (&srv);
}
int main(int argc, char **argv, char **env)
diff --git a/remote/app/remoted.c b/remote/app/remoted.c
index 26f16cf..5d58681 100644
--- a/remote/app/remoted.c
+++ b/remote/app/remoted.c
@@ -11,6 +11,8 @@
#include
#include
+#include
+
// to quit them properly if a signal occurs
struct service srv;
@@ -25,14 +27,42 @@ void handle_signal (int signalnumber)
exit (EXIT_SUCCESS);
}
+void usage ()
+{
+ fprintf (stderr, "remoted [-d ] [-h]\n");
+}
+
/* TODO: handle command line arguments */
+
+// cmdline: remoted -d
void remoted_cmd_args (int argc, char **argv, char **env
, struct remoted_ctx *ctx)
{
- (void) argc;
- (void) argv;
(void) env;
(void) ctx;
+
+ int c;
+ while ( (c = getopt(argc, argv, "hd:")) != -1) {
+ switch (c) {
+ case 'd':
+ ctx->unix_socket_dir = malloc (strlen (optarg) +1);
+ strncpy (ctx->unix_socket_dir, optarg, strlen (optarg));
+ log_debug ("remoted unix socket dir: %s", ctx->unix_socket_dir);
+ break;
+ case '?':
+ case 'h':
+ usage ();
+ exit (EXIT_FAILURE);
+ default:
+ log_debug ("remoted getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc) {
+ log_debug ("remoted non-option ARGV-elements:");
+ while (optind < argc)
+ log_debug ("\t%s", argv[optind++]);
+ }
}
/* TODO: handle authorizations */
@@ -42,9 +72,7 @@ int remoted_auth_conf (struct remoted_ctx *ctx)
return 0;
}
-
-int
-main(int argc, char **argv, char **env)
+int main(int argc, char **argv, char **env)
{
struct remoted_ctx ctx;
memset (&ctx, 0, sizeof (struct remoted_ctx));
@@ -75,7 +103,7 @@ main(int argc, char **argv, char **env)
// TODO: here comes pledge (openbsd)
// the service will loop until the end of time, a specific message, a signal
- remoted_main_loop (&srv);
+ remoted_main_loop (&srv, &ctx);
// the application will shut down, and remove the service unix socket
if (srv_close (&srv) < 0) {
@@ -83,5 +111,7 @@ main(int argc, char **argv, char **env)
}
log_info ("remoted ended");
+ remoted_free_ctx (&ctx);
+
return EXIT_SUCCESS;
}
diff --git a/remote/lib/msg.c b/remote/lib/msg.c
new file mode 100644
index 0000000..2708f91
--- /dev/null
+++ b/remote/lib/msg.c
@@ -0,0 +1,109 @@
+#include
+#include
+#include
+
+#include "msg.h"
+#include "../../core/error.h"
+
+void remote_msg_serialize (const struct remoted_msg *msg, char **data, size_t *len)
+{
+ if (msg == NULL) {
+ handle_err ("remote remote_msg_serialize", "msg == NULL");
+ return;
+ }
+
+ if (data == NULL) {
+ handle_err ("remote remote_msg_serialize", "data == NULL");
+ return;
+ }
+
+ if (*data != NULL) {
+ handle_err ("remote remote_msg_serialize", "*data != NULL");
+ return;
+ }
+
+ if (len == NULL) {
+ handle_err ("remote remote_msg_serialize", "len == NULL");
+ return;
+ }
+
+ // buflen = remote msg type (1) + size_t (16) + data
+ size_t buflen = 1 + sizeof (size_t) + msg->datalen;
+
+ if (buflen > BUFSIZ) {
+ handle_err ("remote remote_msg_serialize", "datalen too high");
+ return;
+ }
+
+ char *buf = malloc (buflen);
+ memset (buf, 0, buflen);
+
+ size_t offset = 0;
+
+ // msg type
+ buf[offset++] = msg->type;
+
+ // data
+ memcpy (buf + offset, &msg->datalen, sizeof (size_t));
+ offset += sizeof (size_t);
+ memcpy (buf + offset, msg->data, msg->datalen);
+ offset += msg->datalen;
+
+ *data = buf;
+ *len = buflen;
+}
+
+void remote_msg_unserialize (struct remoted_msg *msg, const char *buf, size_t mlen)
+{
+ if (msg == NULL) {
+ handle_err ("remote remote_msg_unserialize", "msg == NULL");
+ return;
+ }
+
+ remote_msg_free (msg);
+
+ if (mlen > BUFSIZ) {
+ handle_err ("remote remote_msg_unserialize", "mlen > BUFSIZ");
+ return;
+ }
+
+ size_t offset = 0;
+
+ // msg type
+ msg->type = buf[offset++];
+
+ // data
+ memcpy (&msg->datalen, buf + offset, sizeof (size_t));
+ if (msg->datalen > BUFSIZ) {
+ handle_err ("remote remote_msg_unserialize", "datalen > BUFSIZ");
+ return;
+ }
+ msg->data = malloc (msg->datalen);
+ memset (msg->data, 0, msg->datalen);
+ offset += sizeof (size_t);
+ memcpy (msg->data, buf + offset, msg->datalen);
+ offset += msg->datalen;
+}
+
+void remote_msg_free (struct remoted_msg *msg)
+{
+ if (msg == NULL) {
+ handle_err ("remote remote_msg_free", "msg == NULL");
+ return;
+ }
+
+ if (msg->data) {
+ free (msg->data);
+ msg->data = NULL;
+ }
+}
+
+void remote_msg_print (const struct remoted_msg *msg)
+{
+ if (msg == NULL) {
+ handle_err ("remote remote_msg_print", "msg == NULL");
+ return;
+ }
+
+ printf ("msg: type=%d data=%s\n", msg->type, msg->data);
+}
diff --git a/remote/lib/msg.h b/remote/lib/msg.h
new file mode 100644
index 0000000..aa6d435
--- /dev/null
+++ b/remote/lib/msg.h
@@ -0,0 +1,20 @@
+#ifndef __REMOTE_MSG_H__
+#define __REMOTE_MSG_H__
+
+#define REMOTE_MSG_TYPE_CONNECT 1
+#define REMOTE_MSG_TYPE_LISTEN 2
+#define REMOTE_MSG_TYPE_PUB 3
+
+struct remoted_msg {
+ unsigned char type; // message types = commands (connect, listen, ...)
+ char *data;
+ size_t datalen;
+};
+
+void remote_msg_serialize (const struct remoted_msg *msg, char **data, size_t *len);
+void remote_msg_unserialize (struct remoted_msg *msg, const char *data, size_t len);
+
+void remote_msg_free (struct remoted_msg *msg);
+void remote_msg_print (const struct remoted_msg *msg);
+
+#endif
diff --git a/remote/lib/remote.h b/remote/lib/remote.h
deleted file mode 100644
index 2641984..0000000
--- a/remote/lib/remote.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef __REMOTE_H__
-#define __REMOTE_H__
-
-#include "../../core/process.h"
-#include "../../core/msg.h"
-
-/* TODO */
-
-#endif
diff --git a/remote/lib/remotec.c b/remote/lib/remotec.c
new file mode 100644
index 0000000..5342f20
--- /dev/null
+++ b/remote/lib/remotec.c
@@ -0,0 +1,74 @@
+#include "../../core/communication.h"
+#include "../../core/error.h"
+#include "msg.h"
+#include "remotec.h"
+#include "remoted.h"
+#include
+#include
+#include
+
+int remotec_connection (int argc, char **argv, char **env, struct service *srv)
+{
+ int ret = app_connection (argc, argv, env
+ , srv, REMOTED_SERVICE_NAME, NULL, 0);
+
+ if (ret != 0) {
+ handle_err ("remote remotec_connection", "app_connection != 0");
+ }
+
+ return ret;
+}
+
+int remotec_disconnection (struct service *srv)
+{
+ return app_close (srv);
+}
+
+int remotec_msg_send (struct service *srv, const struct remoted_msg * m)
+{
+ size_t msize = 0;
+ char * buf = NULL;
+ remote_msg_serialize (m, &buf, &msize);
+
+ struct msg m_data;
+ memset (&m_data, 0, sizeof (struct msg));
+
+ // format the connection msg
+ if (msg_format_data (&m_data, buf, msize) < 0) {
+ handle_err ("remotec_msg_send", "msg_format_data");
+ if (buf != NULL)
+ free (buf);
+ return -1;
+ }
+
+ app_write (srv, &m_data);
+ msg_free (&m_data);
+
+ if (buf != NULL)
+ free(buf);
+
+ return 0;
+}
+
+int remotec_msg_recv (struct service *srv, struct remoted_msg *m)
+{
+ if (srv == NULL) {
+ handle_err ("remotec_msg_recv", "srv == NULL");
+ return -1;
+ }
+
+ if (m == NULL) {
+ handle_err ("remotec_msg_recv", "m == NULL");
+ return -1;
+ }
+
+ struct msg m_recv;
+ memset (&m_recv, 0, sizeof (struct msg));
+
+ app_read (srv, &m_recv);
+ remote_msg_unserialize (m, m_recv.val, m_recv.valsize);
+
+ msg_free (&m_recv);
+
+ return 0;
+}
diff --git a/remote/lib/remotec.h b/remote/lib/remotec.h
new file mode 100644
index 0000000..dadcad6
--- /dev/null
+++ b/remote/lib/remotec.h
@@ -0,0 +1,16 @@
+#ifndef __REMOTEC_H__
+#define __REMOTEC_H__
+
+#include "../../core/process.h"
+#include "../../core/msg.h"
+#include "remoted.h"
+
+/* TODO */
+
+int remotec_connection (int argc, char **argv, char **env, struct service *srv);
+int remotec_disconnection (struct service *srv);
+
+int remotec_msg_send (struct service *srv, const struct remoted_msg *msg);
+int remotec_msg_recv (struct service *srv, struct remoted_msg *msg);
+
+#endif
diff --git a/remote/lib/remoted.c b/remote/lib/remoted.c
index e442fa2..4822a2e 100644
--- a/remote/lib/remoted.c
+++ b/remote/lib/remoted.c
@@ -11,9 +11,139 @@
#include
#include
-void remoted_main_loop (struct service *srv)
+/**
+ * new connection, once accepted the process is added to the array_proc
+ * structure to be checked periodically for new messages
+ */
+void handle_new_connection (struct service *srv, struct array_proc *ap)
{
- (void) srv;
- log_debug ("remoted entering main loop");
- /* TODO */
+ struct process *p = malloc(sizeof(struct process));
+ memset(p, 0, sizeof(struct process));
+
+ if (srv_accept (srv, p) < 0) {
+ handle_error("srv_accept < 0");
+ } else {
+ log_debug ("remoted, new connection", p->proc_fd);
+ }
+
+ if (add_proc (ap, p) < 0) {
+ handle_error("add_proc < 0");
+ }
+}
+
+void handle_new_msg (struct array_proc *ap, struct array_proc *proc_to_read)
+{
+ struct msg m;
+ memset (&m, 0, sizeof (struct msg));
+ int i;
+ for (i = 0; i < proc_to_read->size; i++) {
+ if (srv_read (proc_to_read->tab_proc[i], &m) < 0) {
+ handle_error("srv_read < 0");
+ }
+
+ mprint_hexa ("msg received: ", (unsigned char *) m.val, m.valsize);
+
+ // close the process then delete it from the process array
+ if (m.type == MSG_TYPE_CLOSE) {
+ struct process *p = proc_to_read->tab_proc[i];
+
+ log_debug ("remoted, proc %d disconnecting", p->proc_fd);
+
+ // close the connection to the process
+ if (srv_close_proc (p) < 0)
+ handle_error( "srv_close_proc < 0");
+
+ // remove the process from the processes list
+ if (del_proc (ap, p) < 0)
+ handle_error( "del_proc < 0");
+ if (del_proc (proc_to_read, p) < 0)
+ handle_err( "handle_new_msg", "del_proc < 0");
+
+ msg_free (&m);
+
+ // free process
+ free (p);
+
+ i--;
+ continue;
+ }
+
+#if 0
+ struct pubsub_msg m_data;
+ memset (&m_data, 0, sizeof (struct pubsub_msg));
+
+ pubsub_msg_unserialize (&m_data, m.val, m.valsize);
+
+ if (m_data.type == PUBSUB_MSG_TYPE_SUB) {
+ printf ("proc %d subscribing to %s\n"
+ , proc_to_read->tab_proc[i]->proc_fd
+ , m_data.chan);
+ pubsubd_channels_subscribe (chans
+ , m_data.chan, proc_to_read->tab_proc[i]);
+ }
+
+ if (m_data.type == PUBSUB_MSG_TYPE_UNSUB) {
+ printf ("proc %d unsubscribing to %s\n"
+ , proc_to_read->tab_proc[i]->proc_fd
+ , m_data.chan);
+ pubsubd_channels_unsubscribe (chans
+ , m_data.chan, proc_to_read->tab_proc[i]);
+ }
+
+ if (m_data.type == PUBSUB_MSG_TYPE_PUB) {
+ printf ("proc %d publishing to %s\n"
+ , proc_to_read->tab_proc[i]->proc_fd
+ , m_data.chan);
+ struct channel *chan = pubsubd_channel_search (chans, m_data.chan);
+ if (chan == NULL) {
+ handle_err ("handle_new_msg", "publish on nonexistent channel");
+ msg_free (&m);
+ return ;
+ }
+ pubsubd_send (chan->subs, &m_data);
+ }
+
+ pubsub_msg_free (&m_data);
+#endif
+ msg_free (&m);
+ }
+}
+
+void remoted_main_loop (struct service *srv, struct remoted_ctx *ctx)
+{
+ log_debug ("remoted entering main loop");
+ int i, ret = 0;
+
+ struct array_proc ap;
+ memset(&ap, 0, sizeof(struct array_proc));
+
+ struct array_proc proc_to_read;
+ memset(&proc_to_read, 0, sizeof(struct array_proc));
+
+ while(1) {
+ /* TODO: authorizations */
+ ret = srv_select (&ap, srv, &proc_to_read);
+
+ if (ret == CONNECTION) {
+ handle_new_connection (srv, &ap);
+ } else if (ret == APPLICATION) {
+ handle_new_msg (&ap, &proc_to_read);
+ } else { // both new connection and new msg from at least one client
+ handle_new_connection (srv, &ap);
+ handle_new_msg (&ap, &proc_to_read);
+ }
+ array_proc_free (&proc_to_read);
+ }
+
+ for (i = 0; i < ap.size; i++) {
+ if (srv_close_proc (ap.tab_proc[i]) < 0) {
+ handle_error( "srv_close_proc < 0");
+ }
+ }
+}
+
+void remoted_free_ctx (struct remoted_ctx *ctx)
+{
+ if (ctx->unix_socket_dir != NULL)
+ free (ctx->unix_socket_dir), ctx->unix_socket_dir = NULL;
}
diff --git a/remote/lib/remoted.h b/remote/lib/remoted.h
index 4269c03..735e1af 100644
--- a/remote/lib/remoted.h
+++ b/remote/lib/remoted.h
@@ -3,13 +3,16 @@
#include "../../core/process.h"
#include "../../core/msg.h"
+#include "msg.h"
#define REMOTED_SERVICE_NAME "remoted"
struct remoted_ctx {
- /* TODO */
+ char * unix_socket_dir;
+ /* TODO: authorizations */
};
-void remoted_main_loop (struct service *srv);
+void remoted_main_loop (struct service *srv, struct remoted_ctx *ctx);
+void remoted_free_ctx (struct remoted_ctx *ctx);
#endif