chiark / gitweb /
Remove build products
[sympathy.git] / apps / mainloop.c
index f515478810cf824ca0fb9ce251c025019ac41a5e..a54f59cab2a319f5050e341b35b979045c9bc27d 100644 (file)
@@ -1,4 +1,4 @@
-/*
+/* 
  * mainloop.c:
  *
  * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
  *
  */
 
-static char rcsid[] = "$Id$";
+static char rcsid[] =
+  "$Id: mainloop.c,v 1.33 2008/05/09 12:35:57 james Exp $";
 
-/*
- * $Log$
+/* 
+ * $Log: mainloop.c,v $
+ * Revision 1.33  2008/05/09 12:35:57  james
+ * *** empty log message ***
+ *
+ * Revision 1.32  2008/03/11 17:56:50  james
+ * *** empty log message ***
+ *
+ * Revision 1.31  2008/03/11 17:56:04  james
+ * *** empty log message ***
+ *
+ * Revision 1.30  2008/03/11 17:47:24  james
+ * *** empty log message ***
+ *
+ * Revision 1.29  2008/03/10 11:49:32  james
+ * *** empty log message ***
+ *
+ * Revision 1.28  2008/03/07 13:56:39  james
+ * *** empty log message ***
+ *
+ * Revision 1.27  2008/03/07 13:16:02  james
+ * *** empty log message ***
+ *
+ * Revision 1.26  2008/03/06 21:34:09  james
+ * *** empty log message ***
+ *
+ * Revision 1.25  2008/03/06 21:33:02  james
+ * *** empty log message ***
+ *
+ * Revision 1.24  2008/03/06 16:49:39  james
+ * *** empty log message ***
+ *
+ * Revision 1.23  2008/03/06 16:49:05  james
+ * *** empty log message ***
+ *
+ * Revision 1.22  2008/03/03 06:04:42  james
+ * *** empty log message ***
+ *
+ * Revision 1.21  2008/03/02 10:27:24  james
+ * *** empty log message ***
+ *
+ * Revision 1.20  2008/02/28 16:57:51  james
+ * *** empty log message ***
+ *
+ * Revision 1.19  2008/02/28 16:37:16  james
+ * *** empty log message ***
+ *
+ * Revision 1.18  2008/02/28 11:27:48  james
+ * *** empty log message ***
+ *
+ * Revision 1.17  2008/02/27 09:42:53  james
+ * *** empty log message ***
+ *
+ * Revision 1.16  2008/02/27 09:42:21  james
+ * *** empty log message ***
+ *
+ * Revision 1.15  2008/02/27 01:31:38  james
+ * *** empty log message ***
+ *
+ * Revision 1.14  2008/02/27 01:31:14  james
+ * *** empty log message ***
+ *
+ * Revision 1.13  2008/02/26 23:56:12  james
+ * *** empty log message ***
+ *
+ * Revision 1.12  2008/02/26 23:23:16  james
+ * *** empty log message ***
+ *
+ * Revision 1.11  2008/02/24 00:43:55  james
+ * *** empty log message ***
+ *
+ * Revision 1.10  2008/02/23 13:05:57  staffcvs
+ * *** empty log message ***
+ *
+ * Revision 1.9  2008/02/23 11:48:51  james
+ * *** empty log message ***
+ *
+ * Revision 1.8  2008/02/22 23:39:30  james
+ * *** empty log message ***
+ *
+ * Revision 1.7  2008/02/20 20:16:07  james
+ * *** empty log message ***
+ *
+ * Revision 1.6  2008/02/20 19:44:37  james
+ * @@
+ *
+ * Revision 1.5  2008/02/20 18:31:44  james
+ * *** empty log message ***
+ *
+ * Revision 1.4  2008/02/20 17:18:33  james
+ * *** empty log message ***
+ *
  * Revision 1.3  2008/02/20 02:11:35  james
  * *** empty log message ***
  *
@@ -59,10 +150,11 @@ static char rcsid[] = "$Id$";
 
 #include <sys/time.h>
 #include <sympathy.h>
+#include "mainloop.h"
 
-#include "client.h"
 #include "clients.h"
 
+
 typedef struct
 {
   int nclients;
@@ -230,11 +322,11 @@ check_status (Context * c, Clients * cs)
   status = get_status (c->t, cs);
   if (!memcmp (&status, &old_status, sizeof (status)))
     return;
-  old_status = status;
-
 
   log_line_changes (c, old_status.lines, status.lines);
 
+  old_status = status;
+
   ptr += sprintf (ptr, "CTRL-B ");
 
   t = c->t->name;
@@ -265,7 +357,6 @@ check_status (Context * c, Clients * cs)
       while (*t)
         *(ptr++) = *(t++);
     }
-
 #if 0
   if (status.lines & TIOCM_CD)
     {
@@ -285,39 +376,67 @@ check_status (Context * c, Clients * cs)
     sprintf (ptr, ", %d client%s", status.nclients,
              (status.nclients == 1) ? "" : "s");
 
+  if (c->tp->biterrs)
+    {
+
+      ptr +=
+        sprintf (ptr, ", %d err%s", c->tp->biterrs,
+                 (c->tp->biterrs == 1) ? "" : "s");
+
+      if (c->tp->guessed_baud == -1)
+        {
+          ptr += sprintf (ptr, " try higher");
+        }
+      else if (c->tp->guessed_baud > 0)
+        {
+          ptr += sprintf (ptr, " try %db", c->tp->guessed_baud);
+        }
+    }
+
   *ptr = 0;
 
+#if 0
+  log_f (c->l, "%s:%d %s", __FILE__, __LINE__, buf);
+#endif
+
   if (cs)
     send_status (cs, buf);
   else
-    cmd_new_status (c->d, c, m->status.status);
+    cmd_new_status (c->d, c, buf);
 
 }
 
 
-static void
-msg_from_server (IPC_Msg * m, Context * c)
+static int
+msg_from_server (ANSI * a, IPC_Msg * m, Context * c)
 {
+  int err = 0;
   switch (m->hdr.type)
     {
 
     case IPC_MSG_TYPE_NOOP:
       break;
     case IPC_MSG_TYPE_DEBUG:
-//          fprintf (stderr,"%p [%d] %s\n", m, m->hdr.size , m->debug.msg );
+      // fprintf (stderr,"%p [%d] %s\n", m, m->hdr.size , m->debug.msg );
       break;
     case IPC_MSG_TYPE_HISTORY:
       history_add (c->h, m->history.history.line);
       break;
     case IPC_MSG_TYPE_VT102:
       if (sizeof (VT102) != m->vt102.len)
-        abort ();
+        crash_out ("sizeof(VT102) differs in client and server");
 
       *(c->v) = m->vt102.vt102;
-       //FIXME HTML hook
+
+      if (a->one_shot)
+        {
+          a->one_shot (a, &c->v->crt);
+          err++;                /* Simulate a fatal write error enclosing tty 
+                                 */
+        }
       break;
     case IPC_MSG_TYPE_TERM:
-      vt102_parse (c, m->term.term, m->term.len);
+      err += tty_parse (c, m->term.term, m->term.len);
       break;
     case IPC_MSG_TYPE_STATUS:
       cmd_new_status (c->d, c, m->status.status);
@@ -325,53 +444,53 @@ msg_from_server (IPC_Msg * m, Context * c)
     default:
       fprintf (stderr, "Unhandeled message type %d\n", m->hdr.type);
     }
+  return err;
 }
 
 
 void
-mainloop (TTY * tty, Socket * server_socket, Socket * client_socket, Ansi * a,
-          Log * log)
+mainloop (Context * c, ANSI * ansi, Socket * server_socket,
+          Socket * client_socket)
 {
   fd_set rfds, wfds;
-  Context c;
   Clients *clients;
 
+  c->tp = tty_parser_new ();
+  c->u = utf8_new ();
 
-  c.v = vt102_new ();
-  c.h = history_new (200);
-  c.l = log
-    /* are we being fed by a tty or a socket */
-    if (client_socket)
+  /* are we being fed by a tty or a socket */
+  if (client_socket)
     {
       if (server_socket)
-        abort ();
-      c.s = client_socket;
-      c.k = keydis_ipc_new (client_socket);
+        crash_out ("mainloop cannot both be a server and a client");
+      c->k = keydis_ipc_new (client_socket);
     }
   else
     {
-      if (!tty)
-        abort ();
-      c.t = tty;
-      c.k = keydis_vt102_new ();
+      if (!c->t)
+        crash_out ("mainloop must have either a client_socket or a terminal");
+      c->k = keydis_vt102_new ();
     }
 
   /* do we have an upstream terminal to talk to */
   /* if so start a command parser */
   if (ansi)
     {
-      c.d = cmd_new ();
+      c->d = cmd_new ();
     }
   else
     {
-      c.d = NULL;
+      c->d = NULL;
     }
 
 
+  vt102_reset (c);
+
+
   if (server_socket)
     {
       if (client_socket)
-        abort ();
+        crash_out ("mainloop cannot both be a server and a client");
       clients = clients_new ();
     }
   else
@@ -381,16 +500,20 @@ mainloop (TTY * tty, Socket * server_socket, Socket * client_socket, Ansi * a,
 
   for (;;)
     {
-      struct timeval tv = { 1, 0 };
+      struct timeval tv = { 0, 250000 };
 
-      /*update the status lines, locally or remotely*/
-      check_status (&c, clients);
+      if ((c->d) && (c->d->disconnect))
+        break;
+
+      /* update the status lines, locally or remotely */
+      if (c->t)
+        check_status (c, clients);
 
       FD_ZERO (&rfds);
       FD_ZERO (&wfds);
 
-      if (c.t)
-        tty_pre_select (c.t, &rfds, &wfds);
+      if (c->t)
+        tty_pre_select (c->t, &rfds, &wfds);
 
       if (server_socket)
         {
@@ -401,80 +524,86 @@ mainloop (TTY * tty, Socket * server_socket, Socket * client_socket, Ansi * a,
       if (client_socket)
         socket_pre_select (client_socket, &rfds, &wfds);
 
-      if (ansi)
+      if (ansi && ansi->terminal)
         tty_pre_select (ansi->terminal, &rfds, &wfds);
 
       select (FD_SETSIZE, &rfds, &wfds, NULL, &tv);
 
-      /*any message from clients, or new connexions */
+      /* any message from clients, or new connexions */
       if (server_socket)
         {
           Socket *new_client_socket;
           if (FD_ISSET (server_socket->fd, &rfds)
-              && ((new_client_socket = socket_accept (s))))
+              && ((new_client_socket = socket_accept (server_socket))))
             {
               {
                 Client *new_client;
-                /*New client connexion */
+                /* New client connexion */
                 new_client =
-                  clients_new_client (clients, new_client_socket, &c);
+                  clients_new_client (clients, new_client_socket, c);
 
-                send_history (c.h, new_client);
-                send_vt102 (c.v, new_client);
 
               }
             }
 
-          clients_post_select (clients, &c, &rfds, &wfds);
+          clients_post_select (clients, c, &rfds, &wfds);
         }
 
-      /*any data from the port */
-      if (c.t && FD_ISSET (c.t->rfd, &rfds))
+      /* any data from the port */
+      if (c->t && FD_ISSET (c->t->rfd, &rfds))
         {
           char buf[IPC_MAX_BUF];
           int red;
 
-          red = c.t->recv (c.t, buf, sizeof (buf));
+          red = c->t->recv (c->t, buf, sizeof (buf));
 
           if (red < 0)
             break;
 
           if (red)
             {
-              send_output (clients, buf, red);
-              vt102_parse (&c, buf, red);
+              if (clients)
+                send_output (clients, buf, red);
+              if (tty_parse (c, buf, red))
+                break;
             }
         }
 
 
 
-      /*any data from the server*/
+      /* any data from the server */
       if (client_socket)
         {
+          int err = 0;
+
           if (socket_post_select (client_socket, &rfds, &wfds))
             break;
 
-          while (client_socket->msg)
+          while (client_socket->msg && !err)
             {
-              msg_from_server (client_socket->msg, &c);
+              err += msg_from_server (ansi, client_socket->msg, c);
               socket_consume_msg (client_socket);
             }
+
+          if (err)
+            break;
         }
 
 
-      /*update our local screen*/
+      /* update our local screen */
       if (ansi)
         {
-          if (ansi_dispatch (ansi, &c))
-            break;
+          if (ansi->dispatch)
+            if (ansi->dispatch (ansi, c))
+              break;
 
-          ansi_update (ansi, &c);
+          if (ansi->update)
+            if (ansi->update (ansi, c))
+              break;
         }
     }
 
   if (clients)
-    {
-      clients_shutdown (clients);
-    }
-  printf ("QUAT\n");
+    clients_shutdown (clients, c);
+  log_f (c->l, "<sympathy is now terminating>");
 }