WIP: skeleton/planning
authorChristian Thaeter <ct@pipapo.org>
Wed, 3 Oct 2007 01:45:34 +0000 (03:45 +0200)
committerChristian Thaeter <ct@pipapo.org>
Wed, 3 Oct 2007 01:45:34 +0000 (03:45 +0200)
main.c
rxpd.c
rxpd.h

diff --git a/main.c b/main.c
index 4ba4998..e064fca 100644 (file)
--- a/main.c
+++ b/main.c
 
 #include "rxpd.c"
 
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <event.h>
+
+
 void
 usage(void)
 {
@@ -35,6 +44,11 @@ usage(void)
     -t port     tcp
     -u name     unix
     -p policy   access policies
+    -i          case insensitive
+    -4          ipv4
+    -6          ipv6
+    -r          resolve names
+    -l log      log hits to logfile
   */
 
 
@@ -42,23 +56,27 @@ usage(void)
 
 
 
-
 int
 main (int argc, char** argv)
 {
-  struct rxpd_base* base = rxpd_init ("./");
+  struct rxpd_base* rxpd = rxpd_init ("./");
+  struct event_base* event = event_init();
 
   // parse commandline args
 
   // read files
-  rxpd_file_load (base, "test");
+  rxpd_file_load (rxpd, "test");
 
   // initialize listening connections
-
-  // eventloop
+  // port 2374
+  rxpd_socket_activate (rxpd_socket_new_tcp4 (rxpd, NULL, 2374));
+  //rxpd_socket_new_unix (rxpd, "/tmp/rxpd");
 
 
+  // eventloop
+  event_dispatch ();
 
   //
   rxpd_destroy ();
+  printf ("OK\n");
 }
diff --git a/rxpd.c b/rxpd.c
index 3c2b1e0..ef78ff3 100644 (file)
--- a/rxpd.c
+++ b/rxpd.c
@@ -21,9 +21,6 @@
 
 #include "rxpd.h"
 
-#include <string.h>
-#include <stdlib.h>
-
 static struct rxpd_base global_base = {NULL};
 
 struct rxpd_base*
@@ -36,6 +33,12 @@ rxpd_init (char* rulesdir)
   if (!global_base.rulesdir) abort();
 
   psplay_init_root (&global_base.files, rxpd_file_cmp, rxpd_file_delete);
+
+  llist_init (&global_base.sockets_pending);
+  llist_init (&global_base.sockets_active);
+  llist_init (&global_base.connections_pending);
+  llist_init (&global_base.connections_active);
+
   return &global_base;
 }
 
@@ -46,6 +49,26 @@ rxpd_destroy (void)
     {
       free (global_base.rulesdir);
       psplay_destroy_root (&global_base.files);
+      LLIST_WHILE_HEAD (&global_base.sockets_pending, n)
+        {
+          struct rxpd_socket* socket = (struct rxpd_socket*)n;
+          rxpd_socket_delete (socket);
+        }
+      LLIST_WHILE_HEAD (&global_base.sockets_active, n)
+        {
+          struct rxpd_socket* socket = (struct rxpd_socket*)n;
+          rxpd_socket_delete (socket);
+        }
+      LLIST_WHILE_HEAD (&global_base.connections_pending, n)
+        {
+          struct rxpd_connection* connection = (struct rxpd_connection*)n;
+          rxpd_connection_delete (connection);
+        }
+      LLIST_WHILE_HEAD (&global_base.connections_active, n)
+        {
+          struct rxpd_connection* connection = (struct rxpd_connection*)n;
+          rxpd_connection_delete (connection);
+        }
     }
 }
 
@@ -75,15 +98,21 @@ rxpd_rule_new (const char* buf)
             {
               regfree (&self->rx);
               char ebuf[256];
-              ebuf[0] = '#';
-              size_t len = regerror (err, NULL, ebuf+1, 255);
-              self->string = malloc(len + strlen(buf) + 2);
+              size_t len = regerror (err, NULL, ebuf, 256);
+              self->string = malloc(len + strlen(buf) + 9);
               if (!self->string) abort();
-              strcpy (self->string, ebuf);
-              strcat (self->string, ": ");
+              strcpy (self->string, "# ");
+              strcat (self->string, ebuf);
+              strcat (self->string, " in '");
               strcat (self->string, buf);
+              strcat (self->string, "'");
             }
         }
+      else
+        {
+          self->string = strdup (buf);
+          if (!self->string) abort();
+        }
     }
   return self;
 }
@@ -129,13 +158,21 @@ rxpd_file_load (struct rxpd_base* base, const char* filename)
   // TODO error handling
   if (!f) abort();
 
+  // TODO test excess line length = error
   while (fgets (buf, 2048, f))
     {
+      size_t last = strlen(buf);
+      if (buf[last-1] == '\n')
+        buf[last-1] = '\0';
+
       struct rxpd_rule* rule;
       rule = rxpd_rule_new (buf);
       if (!rule)
         abort();
 
+
+      printf("%s\n", rule->string);
+
       llist_insert_tail (&file->rules, &rule->node);
     }
 
@@ -167,3 +204,160 @@ rxpd_file_cmp (const void* A, const void* B)
 {
   return strcmp (A, B);
 }
+
+
+//
+
+struct rxpd_socket*
+rxpd_socket_new_tcp4 (struct rxpd_base* base, const char* addr, unsigned short port)
+{
+  struct rxpd_socket* self = malloc (sizeof (struct rxpd_socket));
+  if (!self)
+    abort();
+
+  self->base = base;
+
+  llist_init (&self->node);
+
+  self->fd = socket (PF_INET, SOCK_STREAM, 0);
+  if (self->fd == -1)
+    abort ();
+
+  struct sockaddr_in listen_addr;
+  memset (&listen_addr, 0, sizeof (listen_addr));
+
+  listen_addr.sin_family = AF_INET;
+  if (inet_aton (addr?addr:"0.0.0.0", &listen_addr.sin_addr) == 0)
+    abort();
+  listen_addr.sin_port = htons(port);
+
+  if (bind (self->fd, (struct sockaddr*)&listen_addr, sizeof (listen_addr)) == -1)
+    abort();
+
+  static int yes=1;
+  if (setsockopt (self->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
+    abort ();
+
+  if (listen (self->fd, 20) == -1)
+    abort ();
+
+  event_set (&self->ev, self->fd, EV_READ, rxpd_socket_accept, self);
+  llist_insert_tail (&base->sockets_pending, &self->node);
+  return self;
+}
+
+
+
+void
+rxpd_socket_delete (struct rxpd_socket* self)
+{
+  llist_unlink (&self->node);
+  event_del (&self->ev);
+  close (self->fd);
+}
+
+struct rxpd_socket*
+rxpd_socket_activate (struct rxpd_socket* self)
+{
+  if (self)
+    {
+      llist_insert_tail (&self->base->sockets_active, &self->node);
+      event_add (&self->ev, NULL);
+    }
+  return self;
+}
+
+struct rxpd_socket*
+rxpd_socket_suspend (struct rxpd_socket* self)
+{
+  if (self)
+    {
+      llist_insert_tail (&self->base->sockets_pending, &self->node);
+      event_del (&self->ev);
+    }
+  return self;
+}
+
+void
+rxpd_socket_accept (int sock, short event, void* ptr)
+{
+  printf ("incoming connection\n");
+
+  //struct rxpd_connection* conn;
+}
+
+///
+
+struct rxpd_connection*
+rxpd_connection_new (struct rxpd_base* base)
+{
+  return NULL;
+}
+
+void
+rxpd_connection_delete (struct rxpd_connection* self)
+{
+  free (self);
+}
+
+int
+rxpd_connection_readline (struct rxpd_connection* self)
+{
+}
+
+void
+rxpd_connection_parse_cmd (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_CHECK (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_APPEND (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_PREPEND (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_REMOVE (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_REPLACE (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_LOAD (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_SAVE (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_DUMP (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_LIST (int sock, short event, void* ptr)
+{
+}
+
+void
+rxpd_connection_cmd_END (int sock, short event, void* ptr)
+{
+}
+
+
diff --git a/rxpd.h b/rxpd.h
index 2345ccc..2d4fe85 100644 (file)
--- a/rxpd.h
+++ b/rxpd.h
 #ifndef RXPD_H
 #define RXPD_H
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <regex.h>
-//#include <>
 #include "llist.h"
 #include "psplay.h"
 
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <regex.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <event.h>
 
 #define RXPD_COMMANDS                           \
-{                                               \
-  RXPD_CMD(CHECK),                              \
-  RXPD_CMD(APPEND),                             \
-  RXPD_CMD(PREPEND),                            \
-  RXPD_CMD(REMOVE),                             \
-  RXPD_CMD(REPLACE),                            \
-  RXPD_CMD(LOAD),                               \
-  RXPD_CMD(SAVE),                               \
-  RXPD_CMD(DUMP),                               \
-  RXPD_CMD(LIST),                               \
+  RXPD_CMD(CHECK)                               \
+  RXPD_CMD(APPEND)                              \
+  RXPD_CMD(PREPEND)                             \
+  RXPD_CMD(REMOVE)                              \
+  RXPD_CMD(REPLACE)                             \
+  RXPD_CMD(LOAD)                                \
+  RXPD_CMD(SAVE)                                \
+  RXPD_CMD(DUMP)                                \
+  RXPD_CMD(LIST)                                \
   RXPD_CMD(END)                                 \
-}
 
-#define RXPD_CMD(cmd) RXPD_CMD_##cmd
-enum RXPD_COMMANDS;
+#define RXPD_CMD(cmd) RXPD_CMD_##cmd,
+enum {RXPD_COMMANDS};
 #undef RXPD_CMD
 
 struct rxpd_base;
 struct rxpd_file;
 struct rxpd_rule;
+struct rxpd_socket;
+struct rxpd_connection;
 
 struct rxpd_base
 {
   char* rulesdir;
   psplayroot files;
+
+  llist sockets_pending;
+  llist sockets_active;
+  llist connections_pending;
+  llist connections_active;
 };
 
 
@@ -101,5 +112,69 @@ int
 rxpd_file_cmp (const void* A, const void* B);
 
 
+//
+
+struct rxpd_socket
+{
+  llist node;
+  int fd;
+  struct event ev;
+  struct rxpd_base* base;
+};
+
+
+struct rxpd_socket*
+rxpd_socket_new_tcp4 (struct rxpd_base* base, const char* addr, unsigned short port);
+
+//struct rxpd_socket*
+//rxpd_socket_new_unix (struct rxpd_base* base, const char* name);
+
+void
+rxpd_socket_delete (struct rxpd_socket* self);
+
+void
+rxpd_socket_accept (int sock, short event, void* ptr);
+
+struct rxpd_socket*
+rxpd_socket_activate (struct rxpd_socket* self);
+
+struct rxpd_socket*
+rxpd_socket_suspend (struct rxpd_socket* self);
+
+
+//
+
+struct rxpd_connection
+{
+  llist node;
+  int fd;
+  struct event ev;
+  struct rxpd_base* base;
+
+  struct sockaddr_in peer_addr;
+  
+  char* eol;
+  char* eob;
+  char buffer[4096];
+};
+
+
+struct rxpd_connection*
+rxpd_connection_new (struct rxpd_base* base);
+
+void
+rxpd_connection_delete (struct rxpd_connection* self);
+
+int
+rxpd_connection_readline (struct rxpd_connection* self);
+
+void
+rxpd_connection_parse_cmd (int sock, short event, void* ptr);
+
+/* generate prototypes for each defined command */
+#define RXPD_CMD(cmd) void rxpd_connection_cmd_##cmd (int sock, short event, void* ptr);
+RXPD_COMMANDS
+#undef RXPD_CMD
+
 
 #endif