X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=popproxy.c;h=070738fa2e510fef8e504733acf3209111a28fd9;hb=442dc01c2b410071ff214a22f31adb25a62890b2;hp=78403ba2c05c127229cb59f530f82e208774bb10;hpb=389a08481f681f29ad851c7a312beecaad56c313;p=cascardo%2Frnetproxy.git diff --git a/popproxy.c b/popproxy.c index 78403ba..070738f 100644 --- a/popproxy.c +++ b/popproxy.c @@ -26,8 +26,6 @@ #include #include #include "log.h" -#include "nethook.h" -#include "null.h" #include "pop.h" #include "hcconn.h" @@ -41,12 +39,65 @@ struct pop_address char *port; }; +static HCConn * +server_conn_new (char *server, char *port) +{ + int fd; + HCConn *conn; + HCConn *ssl_conn; + int r; + fd = hc_tcp_connect (server, port); + if (fd < 0) + { + g_warning ("Could not connect to server at %s:%s.", server, port); + return NULL; + } + conn = hc_conn_new (NULL, NULL); + ssl_conn = hc_conn_new (NULL, NULL); + r = hc_conn_set_driver_channel (conn, fd); + if (r != 0) + { + hc_conn_close (ssl_conn); + hc_conn_close (conn); + close (fd); + return NULL; + } + r = hc_conn_set_driver_ssl_client (ssl_conn, conn); + if (r != 0) + { + hc_conn_close (ssl_conn); + hc_conn_close (conn); + return NULL; + } + return ssl_conn; +} + +static void +push_other (HCConn *conn, HCEvent event, gpointer data) +{ + char buffer[4096]; + int r; + switch (event) + { + case HC_EVENT_READ: + while ((r = hc_conn_read (conn, buffer, sizeof (buffer))) > 0) + hc_conn_write (data, buffer, r); + break; + case HC_EVENT_CLOSE: + hc_conn_close (conn); + hc_conn_close (data); + break; + } +} + static void new_client (int fd, struct sockaddr *addr, socklen_t saddr, gpointer data) { HCConn *conn; - net_hook_t *hook; + HCConn *pop_conn; + HCConn *server_conn; struct pop_address *address = data; + int r; if (fd < 0) { g_critical ("Server has received an error event."); @@ -54,18 +105,45 @@ new_client (int fd, struct sockaddr *addr, socklen_t saddr, gpointer data) } g_message ("Received connection from %s.", inet_ntoa (((struct sockaddr_in *) addr)->sin_addr)); + + server_conn = server_conn_new (address->server, address->port); + if (server_conn == NULL) + { + return; + } + conn = hc_conn_new (NULL, NULL); - hc_conn_set_driver_channel (conn, fd); - hook = null_hook_new (conn, address->server, address->port); - pop_hook_new (hook); + r = hc_conn_set_driver_channel (conn, fd); + if (r != 0) + { + hc_conn_close (server_conn); + hc_conn_close (conn); + close (fd); + return; + } + pop_conn = hc_conn_new (NULL, NULL); + r = hc_conn_set_driver_pop (pop_conn, conn); + if (r != 0) + { + hc_conn_close (server_conn); + hc_conn_close (pop_conn); + hc_conn_close (conn); + return; + } + hc_conn_set_callback (pop_conn, push_other, server_conn); + hc_conn_set_callback (server_conn, push_other, pop_conn); + } static gchar *configfile; +static gboolean foreground; static GOptionEntry opt_entries[] = { { "config-file", 'c', 0, G_OPTION_ARG_FILENAME, &configfile, "Configuration file location", "file" }, + { "foreground", 'f', 0, G_OPTION_ARG_NONE, &foreground, + "Run in foreground", 0 }, { NULL } }; @@ -83,15 +161,18 @@ int main (int argc, char **argv) struct pop_address pop_address; gnutls_global_init (); - pop_log_init (); configfile = CONFFILE; opt_ctx = g_option_context_new (""); g_option_context_add_main_entries (opt_ctx, opt_entries, NULL); - if (!g_option_context_parse (opt_ctx, &argc, &argv, NULL)) + + error = NULL; + if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) { - g_log (NULL, G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL, - "Could not parse command line options."); + g_critical ("Could not parse command line options: %s.", + error->message); + g_error_free (error); + exit (1); } g_option_context_free (opt_ctx); @@ -101,8 +182,8 @@ int main (int argc, char **argv) if (g_key_file_load_from_file (keyfile, configfile, G_KEY_FILE_NONE, &error) == FALSE) { - fprintf (stderr, "Could not load configuration file %s: %s.\n", - configfile, error->message); + g_critical ("Could not load configuration file %s: %s.", + configfile, error->message); g_error_free (error); exit (1); } @@ -130,7 +211,7 @@ int main (int argc, char **argv) server_address = g_strdup ("127.0.0.1"); g_error_free (error); } - + error = NULL; server_port = g_key_file_get_string (keyfile, "global", "server_port", &error); if (server_port == NULL && error != NULL) @@ -145,14 +226,17 @@ int main (int argc, char **argv) server_fd = hc_tcp_server (port); if (server_fd < 0) { - fprintf (stderr, "Could not create server.\n"); + g_critical ("Could not create server."); exit (1); } hc_server_add_watch (server_fd, new_client, &pop_address); + pop_log_init (); + g_message ("Listening at %s:%s.", conf_address, port); - daemon (0, 0); + if (!foreground) + daemon (0, 0); g_free (conf_address); g_free (port);