use C stdio streams for sockets
authorChristian Thaeter <ct@pipapo.org>
Sun, 4 Nov 2007 03:01:52 +0000 (04:01 +0100)
committerChristian Thaeter <ct@pipapo.org>
Sun, 4 Nov 2007 03:01:52 +0000 (04:01 +0100)
contrib/irc/xchat/rx.c

index 7c0ebab..c5e9183 100644 (file)
@@ -50,58 +50,11 @@ static struct rx_plugin_data
   const char* port;
   const char* prefix;
   const char* list;
-  int fd;               /* the fd used for CHECK:list */
-  char* eol;
-  char* eob;
-  char buffer[4096];
+  struct addrinfo* addrs;
+  FILE* rxpd;
 } rx_private;
 
 
-static char*
-buffer_readline (struct rx_plugin_data* self)
-{
-  ssize_t r;
-
-  if (self->eol < self->eob)
-    {
-      //there was a line pending, shift buffer left
-      memmove (self->buffer, self->eol+1, self->eob - self->eol - 1);
-      self->eob = (char*)(self->eob - (self->eol - self->buffer + 1));
-      self->eol = self->buffer;
-      // TODO handle \r's
-    }
-
-  do {
-    // find next newline, terminate string there
-    char* i;
-    for (i = self->buffer; i < self->eob; ++i)
-      {
-        if (*i == '\n')
-          {
-            *i = '\0';
-            self->eol = i;
-            // have line, return it
-            return (self->eob == self->buffer) ? NULL : self->buffer;
-          }
-      }
-
-    r = 0;
-    do
-      {
-        r = read (self->fd, self->eob, 4095 - (self->eob - self->buffer));
-      }
-    while (r == -1 && errno == EINTR);
-
-    if (r != -1)
-      self->eob += r;
-
-  } while (r != -1);
-
-  return NULL;
-}
-
-
-
 void
 xchat_plugin_get_info (char **name,
                        char **desc,
@@ -116,51 +69,52 @@ xchat_plugin_get_info (char **name,
 static int
 rxstart_cb (char *word[], char *word_eol[], void *userdata)
 {
-  //  server port list; enables and connects to rxpd", &rx_private);
   struct rx_plugin_data* rx = (struct rx_plugin_data*)userdata;
 
+  if (rx->rxpd)
+    {
+      xchat_printf (ph, "RX: already connected");
+      return XCHAT_EAT_ALL;
+    }
+
   rx->server = strdup (word[2]);
   rx->port = strdup (word[3]);
   rx->list = strdup (word[4]);
 
-  struct addrinfo* addrs = NULL;
   int aierr;
 
   /* resolve peer */
-  aierr = getaddrinfo (rx->server, rx->port, NULL, &addrs);
+  aierr = getaddrinfo (rx->server, rx->port, NULL, &rx->addrs);
   if (aierr)
     {
       xchat_printf (ph, "could not resolve %s:%s, %s\n", rx->server, rx->port, gai_strerror (aierr));
       return XCHAT_EAT_ALL;
     }
 
-  rx->fd = socket (addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
-  if (rx->fd == -1 || connect (rx->fd, addrs->ai_addr, addrs->ai_addrlen))
+  int fd;
+
+  fd = socket (rx->addrs->ai_family, rx->addrs->ai_socktype, rx->addrs->ai_protocol);
+  if (fd == -1 || connect (fd, rx->addrs->ai_addr, rx->addrs->ai_addrlen))
     {
-      freeaddrinfo (addrs);
+      freeaddrinfo (rx->addrs);
+      rx->addrs = NULL;
       xchat_printf (ph, "error connecting %s:%s, %s\n", rx->server, rx->port, strerror (errno));
       return XCHAT_EAT_ALL;
     }
-  freeaddrinfo (addrs);
-
-  struct iovec cmd[3] =
-    {
-      {"CHECK:", sizeof("CHECK:")-1},
-      {(void*)rx->list, strlen (rx->list)},
-      {"\n", 1}
-    };
 
-  ssize_t written = writev (rx->fd, cmd, 3);
-  if (written < cmd[0].iov_len + cmd[1].iov_len + cmd[2].iov_len)
+  rx->rxpd = fdopen (fd, "rb+");
+  if (!rx->rxpd)
     {
-      xchat_printf (ph, "error writing check commmand\n");
-      close (rx->fd);
-      rx->fd = -1;
+      freeaddrinfo (rx->addrs);
+      rx->addrs = NULL;
+      xchat_printf (ph, "error connecting %s:%s, %s\n", rx->server, rx->port, strerror (errno));
       return XCHAT_EAT_ALL;
     }
 
-  if (rx->debug)
-    xchat_printf (ph, "established rxpd connection to %s:%s\n", rx->server, rx->port);
+  fprintf (rx->rxpd, "CHECK:%s\n", rx->list);
+  /*error handling here*/
+
+  xchat_printf (ph, "established rxpd connection to %s:%s\n", rx->server, rx->port);
 
   return XCHAT_EAT_ALL;
 }
@@ -170,16 +124,16 @@ rxstop_cb (char *word[], char *word_eol[], void *userdata)
 {
   struct rx_plugin_data* rx = (struct rx_plugin_data*)userdata;
 
-  if (rx->fd != -1)
+  if (rx->rxpd)
     {
-      close (rx->fd);
-      rx->fd = -1;
-      if (rx->debug)
-        xchat_printf (ph, "closed rxpd connection to %s:%s\n", rx->server, rx->port);
+      fclose (rx->rxpd);
+      rx->rxpd = NULL;
+      freeaddrinfo (rx->addrs);
+      rx->addrs = NULL;
+      xchat_printf (ph, "closed rxpd connection to %s:%s\n", rx->server, rx->port);
     }
   else
-    if (rx->debug)
-      xchat_printf (ph, "no rxpd connection established\n");
+    xchat_printf (ph, "no rxpd connection established\n");
 
   return XCHAT_EAT_ALL;
 }
@@ -226,7 +180,7 @@ rxinfo_cb (char *word[], char *word_eol[], void *userdata)
 {
   struct rx_plugin_data* rx = (struct rx_plugin_data*)userdata;
   xchat_printf (ph, "RX: debugging is %s\n", rx->debug?"on":"off");  
-  if (rx->fd != -1)
+  if (rx->rxpd)
     {
       xchat_printf (ph, "RX: connected to %s:%s\n", rx->server, rx->port);  
       xchat_printf (ph, "RX: using list %s\n", rx->list);
@@ -242,37 +196,31 @@ rxhook_cb (char *word[], char *word_eol[], void *userdata)
 {
   struct rx_plugin_data* rx = (struct rx_plugin_data*)userdata;
 
-  if (rx->fd != -1)
+  if (rx->rxpd)
     {
       /* ok do the checking*/
+      fprintf (rx->rxpd, "%s\n", word_eol[1]);
+
+      // TODO xchat_printf (ph, "RXPD: error writing\n");
 
-      struct iovec check[2] =
-        {
-          {(void*)word_eol[1], strlen (word_eol[1])},
-          {"\n", 1}
-        };
+      char buffer[4096];
 
-      ssize_t written = writev (rx->fd, check, 2);
-      if (written < check[0].iov_len + 1)
-        {
-          xchat_printf (ph, "RXPD: error writing\n");
-          close (rx->fd);
-          rx->fd = -1;
-          return XCHAT_EAT_NONE;
-        }
+      fgets (buffer, 4095, rx->rxpd);
+      /*todo error handling*/
 
-      char* line = buffer_readline (rx);
+      char* nl = strrchr(buffer, '\n');
+      if (nl)
+        *nl = '\0';
 
-      if (rx->debug && !PREFIXCMP(line, "ok:"))
-        xchat_printf (ph, "RXPD: '%s'\n", line);
+      if (rx->debug && !PREFIXCMP(buffer, "ok:"))
+        xchat_printf (ph, "RX: matched '%s'\n", buffer);
 
-      if (PREFIXCMP(line, "ignore:"))
+      if (PREFIXCMP(buffer, "ignore:"))
         return XCHAT_EAT_XCHAT;
       //else if (PREFIXCMP(line, "kick:"))
       //else if (PREFIXCMP(line, "kickban:"))
       //else if (PREFIXCMP(line, "ban:"))
       //else if (PREFIXCMP(line, "op:"))
-
     }
 
   return XCHAT_EAT_NONE;
@@ -316,9 +264,8 @@ xchat_plugin_init (xchat_plugin *plugin_handle,
   rx_private.server = NULL;
   rx_private.port = NULL;
   rx_private.list = NULL;
-  rx_private.fd = -1;
-  rx_private.eol = rx_private.eob = rx_private.buffer;
-  rx_private.buffer [4095] = '\0';
+  rx_private.addrs = NULL;
+  rx_private.rxpd = NULL;
 
   struct commands* itr;
   for (itr = command_table; itr->command; ++itr)
@@ -335,8 +282,11 @@ xchat_plugin_init (xchat_plugin *plugin_handle,
 int
 xchat_plugin_deinit (void)
 {
-  if (rx_private.fd != -1)
-    close (rx_private.fd);
+  if (rx_private.rxpd)
+    fclose (rx_private.rxpd);
+
+  if (rx_private.addrs)
+    freeaddrinfo (rx_private.addrs);
 
   xchat_printf (ph, "rxpd plugin unloaded\n");