summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..509255c
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,206 @@
+/* According to POSIX.1-2001, POSIX.1-2008 */
+#include <sys/select.h>
+
+#include <stdio.h>
+
+#include "error/error.h"
+
+#include "parameters/parameters.h"
+
+#include "irc/irc.h"
+
+#include "meta_net/meta_net.h"
+
+#include "pervasive.h"
+
+static void print_help (const char runnable [const restrict static 1])
+{
+ printf
+ (
+ "JabberHive - IRC Gateway\n"
+ "Software Version %d\n"
+ "Protocol Version %d\n"
+ "\nUsages:\n"
+ " GATEWAY:\t%s SOCKET_NAME IRC_SERVER IRC_NICK IRC_CHANNEL IRC_PORT"
+ " [OPTIONS]\n"
+ " SHOW HELP:\tAnything else.\n"
+ "\nParameters:\n"
+ " SOCKET_NAME:\tValid UNIX socket.\n"
+ " IRC_SERVER:\tAddress of the IRC server. Prefixing with '#' will"
+ " enable SSL.\n"
+ " IRC_NICK:\tIRC nick to be used.\n"
+ " IRC_CHANNEL:\tIRC channel to connect to.\n"
+ " IRC_PORT:\tPort to use for the IRC connection.\n"
+ "\nOptions:\n"
+ " -6, --ipv6:\tEnables IPv6.\n"
+ " -u USERNAME, --username USERNAME:\tSets the IRC username.\n"
+ " -r REALNAME, --realname REALNAME:\tSets the IRC realname.\n"
+ " -p PASSWORD, --password PASSWORD:\tSets the IRC password.\n",
+ JH_PROGRAM_VERSION,
+ JH_PROTOCOL_VERSION,
+ runnable
+ );
+}
+
+static int initialize
+(
+ struct JH_irc irc [const restrict static 1],
+ struct JH_meta_net socket [const restrict static 1],
+ struct JH_parameters params [const restrict static 1],
+ const int argc,
+ const char * argv [const static argc]
+)
+{
+ if (JH_parameters_initialize(params, argc, argv) < 0)
+ {
+ print_help(argv[0]);
+
+ return -1;
+ }
+
+ JH_meta_net_initialize(socket);
+
+ if (JH_irc_initialize(irc, params, socket) < 0)
+ {
+ JH_meta_net_finalize(socket);
+
+ return -1;
+ }
+
+ return 0;
+}
+
+static int connect_all
+(
+ struct JH_irc irc [const restrict static 1],
+ struct JH_meta_net socket [const restrict static 1],
+ struct JH_parameters params [const restrict static 1]
+)
+{
+ if (JH_meta_net_connect(socket, params) < 0)
+ {
+ return -1;
+ }
+
+ if (JH_irc_connect(irc) < 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int event_handling_loop
+(
+ struct JH_irc irc [const restrict static 1],
+ struct JH_meta_net socket [const restrict static 1],
+ struct JH_parameters params [const restrict static 1]
+)
+{
+ struct timeval tv;
+ fd_set in_set, out_set;
+ int fd_max, error;
+
+ for (;;)
+ {
+
+ tv.tv_usec = 250000;
+ tv.tv_sec = 0;
+
+ FD_ZERO(&in_set);
+ FD_ZERO(&out_set);
+
+ fd_max = 0;
+
+ if (JH_irc_pre_select(irc, &in_set, &out_set, &fd_max) < 0)
+ {
+ JH_meta_net_finalize(socket);
+
+ return -1;
+ }
+
+ if
+ (
+ JH_meta_net_pre_select
+ (
+ socket,
+ params,
+ &in_set,
+ &out_set,
+ &fd_max
+ ) < 0
+ )
+ {
+ JH_irc_finalize(irc);
+
+ return -1;
+ }
+
+ error =
+ select
+ (
+ (fd_max + 1),
+ &in_set,
+ &out_set,
+ (fd_set *) NULL,
+ &tv
+ );
+
+ if (error < 0)
+ {
+ JH_ERROR
+ (
+ stderr,
+ "Unable to select the sockets: %s.",
+ strerror(error)
+ );
+ }
+
+ if (JH_irc_post_select(irc, &in_set, &out_set) < 0)
+ {
+ JH_meta_net_finalize(socket);
+
+ return -1;
+ }
+
+ if
+ (
+ JH_meta_net_post_select
+ (
+ socket,
+ params,
+ &in_set,
+ &out_set
+ ) < 0
+ )
+ {
+ JH_irc_finalize(irc);
+
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int main (const int argc, const char * argv [const static argc])
+{
+ struct JH_parameters params;
+ struct JH_meta_net socket;
+ struct JH_irc irc;
+
+ if (initialize(&irc, &socket, &params, argc, argv) < 0)
+ {
+ return -1;
+ }
+
+ if (connect_all(&irc, &socket, &params) < 0)
+ {
+ JH_irc_finalize(&irc);
+ JH_meta_net_finalize(&socket);
+
+ return -1;
+ }
+
+ return event_handling_loop(&irc, &socket, &params);
+}