chiark / gitweb /
*** empty log message ***
[sympathy.git] / apps / sympathyd.c
index 2e45ed1b8d74f2c0eedbc4243608a9f0342a4693..49dd3120bc759b37522d2aca31aeabc9951adc0b 100644 (file)
@@ -6,10 +6,20 @@
  *
  */
 
-static char rcsid[] = "$Id$";
+static char rcsid[] =
+  "$Id$";
 
 /*
  * $Log$
+ * Revision 1.8  2008/02/14 10:34:30  james
+ * *** empty log message ***
+ *
+ * Revision 1.7  2008/02/14 02:46:44  james
+ * *** empty log message ***
+ *
+ * Revision 1.6  2008/02/14 00:57:58  james
+ * *** empty log message ***
+ *
  * Revision 1.5  2008/02/13 18:05:06  james
  * *** empty log message ***
  *
@@ -27,15 +37,219 @@ static char rcsid[] = "$Id$";
  *
  */
 
+#include <sys/time.h>
 #include <sympathy.h>
 
 #include "client.h"
 #include "clients.h"
 
-int main (int argc,char *argv[])
+typedef struct
+{
+  int nclients;
+  int lines;
+  int baud;
+  int crtscts;
+  int cd_edge_sec;
+  int bootstrap;
+} Status;
+
+static Status
+get_status (TTY * t, Clients * cs)
+{
+  static struct timeval last_cd_edge = { 0 };
+  static int last_cd_state = -1;
+  int cd;
+  struct timeval now, dif;
+
+  TTY_Status tty_status = { 0 };
+  Status status;
+
+  tty_get_status (t, &tty_status);
+
+  status.bootstrap = 1;
+  status.nclients = cs->n;
+  status.lines = tty_status.lines;
+  status.baud = tty_status.baud;
+  status.crtscts = (tty_status.termios.c_cflag & CRTSCTS) ? 1 : 0;
+
+  cd = (tty_status.lines & TIOCM_CD) ? 1 : 0;
+
+  if (cd != last_cd_state)
+    {
+      gettimeofday (&last_cd_edge, NULL);
+      last_cd_state = cd;
+    }
+
+  gettimeofday (&now, NULL);
+  timersub (&now, &last_cd_edge, &dif);
+  status.cd_edge_sec = dif.tv_sec;
+
+  return status;
+}
+
+static char *
+line_to_name (int l)
+{
+
+  switch (l)
+    {
+#ifdef TIOCM_LE
+    case TIOCM_LE:
+      return "LE";
+#endif
+#ifdef TIOCM_DTR
+    case TIOCM_DTR:
+      return "DTR";
+#endif
+#ifdef TIOCM_RTS
+    case TIOCM_RTS:
+      return "RTS";
+#endif
+#ifdef TIOCM_ST
+    case TIOCM_ST:
+      return "ST";
+#endif
+#ifdef TIOCM_SR
+    case TIOCM_SR:
+      return "SR";
+#endif
+#ifdef TIOCM_CTS
+    case TIOCM_CTS:
+      return "CTS";
+#endif
+#ifdef TIOCM_CD
+    case TIOCM_CD:
+      return "CD";
+#endif
+#ifdef TIOCM_RI
+    case TIOCM_RI:
+      return "RI";
+#endif
+#ifdef TIOCM_DSR
+    case TIOCM_DSR:
+      return "DSR";
+#endif
+    }
+  return "??";
+}
+
+static void
+log_line_changes (Context * ctx, int old, int new)
+{
+  int dif = old ^ new;
+  int c = 1;
+  char buf[1024], *ptr = buf;
+  char *n;
+
+  if (!dif)
+    return;
+  if (!ctx->l)
+    return;
+
+  n = "<Modem lines changed:";
+
+  while (*n)
+    *(ptr++) = *(n++);
+
+  while (dif >= c)
+    {
+
+      if (dif & c)
+        {
+          *(ptr++) = ' ';
+          *(ptr++) = (new & c) ? '+' : '-';
+          n = line_to_name (c);
+          while (*n)
+            *(ptr++) = *(n++);
+        }
+
+      c <<= 1;
+    }
+  *(ptr++) = '>';
+  *ptr = 0;
+
+
+  ctx->l->log (ctx->l, buf);
+
+}
+
+static char *
+do_line (char *ptr,int lines, int line)
+{
+  char *lname;
+
+  if (!(lines & line))
+    return ptr;
+  lname = line_to_name (line);
+
+  while (*lname)
+    *(ptr++) = *(lname++);
+
+  return ptr;
+}
+
+
+
+static void
+check_status (Context * c, Clients * cs)
+{
+  static Status old_status = { 0 };
+  Status status;
+  char buf[1024];
+  char *ptr = buf;
+  char *t;
+
+  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);
+
+  t=c->t->name;
+  if (!strncmp(t,"/dev/",5)) t+=5;
+  while (*t)
+    *(ptr++) = *(t++);
+
+  ptr += sprintf (ptr, " %db", status.baud);
+
+  ptr = do_line (ptr, status.lines, TIOCM_RTS);
+  ptr = do_line (ptr, status.lines, TIOCM_CTS);
+  ptr = do_line (ptr, status.lines, TIOCM_DTR);
+  ptr = do_line (ptr, status.lines, TIOCM_DSR);
+  ptr = do_line (ptr, status.lines, TIOCM_RI);
+
+  if (status.crtscts) {
+       t=", Flow";
+  while (*t)
+    *(ptr++) = *(t++);
+    }
+  if (status.lines & TIOCM_CD)
+    {
+      ptr +=
+        sprintf (ptr, ", On %d.%d", status.cd_edge_sec / 60,
+                 status.cd_edge_sec % 60);
+    }
+  else
+    {
+      ptr +=
+        sprintf (ptr, ", Off %d.%d", status.cd_edge_sec / 60,
+                 status.cd_edge_sec % 60);
+    }
+
+  ptr += sprintf (ptr, ", %d client%s", status.nclients,(status.nclients==1) ? "":"s");
+
+  *ptr = 0;
+
+  send_status (cs, buf);
+}
+
+int
+main (int argc, char *argv[])
 {
   fd_set rfds, wfds;
-  ANSI a = { 0 };
   Context c;
   Socket *s, *cs;
   Clients *clients;
@@ -47,37 +261,41 @@ int main (int argc,char *argv[])
   c.v = vt102_new ();
   c.h = history_new (200);
   c.l = file_log_new ("log");
+  c.k = keydis_vt102_new (&c);
 
-  terminal_register_handlers ();
-  a.terminal = terminal_open (0, 1);
-
-  ansi_reset (&a, NULL);
 
-  clients=clients_new();
+  clients = clients_new ();
 
   for (;;)
     {
-      struct timeval tv = { 0, 100000 };
+      struct timeval tv = { 1, 0 };
 
+      check_status (&c, clients);
 
       FD_ZERO (&rfds);
       FD_ZERO (&wfds);
 
-      tty_pre_select (c.t, &rfds,&wfds);
-      tty_pre_select (a.terminal, &rfds,&wfds);
+      tty_pre_select (c.t, &rfds, &wfds);
 
-      socket_pre_select (s, &rfds, &wfds);
+      FD_SET (s->fd, &rfds);
 
-      clients_pre_select (clients,&rfds,&wfds);
+      socket_pre_select (s, &rfds, &wfds);
 
-      select (FD_SETSIZE, &rfds, NULL, NULL, &tv);
+      clients_pre_select (clients, &rfds, &wfds);
 
-      cs = socket_post_select (s, &rfds, &wfds);
+      select (FD_SETSIZE, &rfds, &wfds, NULL, &tv);
 
-      if (cs)
+      if (FD_ISSET (s->fd, &rfds) && ((cs = socket_accept (s))))
         {
-          /*New client connexion */
-          clients_new_client (clients, cs, &c);
+          {
+            Client *cl;
+            /*New client connexion */
+            cl = clients_new_client (clients, cs, &c);
+
+            send_history (c.h, cl);
+            send_vt102 (c.v, cl);
+
+          }
         }
 
 
@@ -85,7 +303,7 @@ int main (int argc,char *argv[])
 
       if (FD_ISSET (c.t->rfd, &rfds))
         {
-          char buf[1024];
+          char buf[IPC_MAX_BUF];
           int red;
 
           red = c.t->recv (c.t, buf, sizeof (buf));
@@ -95,17 +313,16 @@ int main (int argc,char *argv[])
 
           if (red)
             {
-              clients_output (clients, buf, red);
+              send_output (clients, buf, red);
               vt102_parse (&c, buf, red);
             }
         }
 
-      ansi_dispatch (&a, &c);
-      ansi_update (&a, &c);
+
+
     }
 
   clients_shutdown (clients);
-  ansi_terminal_reset (&a);
   terminal_atexit ();
   printf ("QUAT\n");
 }