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