chiark / gitweb /
*** empty log message ***
[sympathy.git] / apps / sympathyd.c
index 8f45ca58ba557969499ae34fc9a24abbbcf6f76c..49dd3120bc759b37522d2aca31aeabc9951adc0b 100644 (file)
@@ -11,6 +11,9 @@ static char rcsid[] =
 
 /*
  * $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 ***
  *
@@ -34,47 +37,219 @@ static char rcsid[] =
  *
  */
 
+#include <sys/time.h>
 #include <sympathy.h>
 
 #include "client.h"
 #include "clients.h"
 
+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
-send_history (History * h, Client * c)
+log_line_changes (Context * ctx, int old, int new)
 {
-  int rptr = h->wptr;
+  int dif = old ^ new;
+  int c = 1;
+  char buf[1024], *ptr = buf;
+  char *n;
 
-  HISTORY_INC (h, rptr);
+  if (!dif)
+    return;
+  if (!ctx->l)
+    return;
 
-  HISTORY_INC (h, rptr);
-  while (rptr != h->wptr)
-    {
-      History_ent *l = &h->lines[rptr];
-      if (l->valid)
-        {
+  n = "<Modem lines changed:";
 
-          if (ipc_msg_send_history (c->s, l))
-            c->dead++;
+  while (*n)
+    *(ptr++) = *(n++);
+
+  while (dif >= c)
+    {
 
+      if (dif & c)
+        {
+          *(ptr++) = ' ';
+          *(ptr++) = (new & c) ? '+' : '-';
+          n = line_to_name (c);
+          while (*n)
+            *(ptr++) = *(n++);
         }
-      HISTORY_INC (h, rptr);
+
+      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
-send_vt102 (VT102 * v, Client * c)
+check_status (Context * c, Clients * cs)
 {
-  if (ipc_msg_send_vt102 (c->s, v))
-    c->dead++;
+  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;
@@ -88,26 +263,19 @@ main (int argc, char *argv[])
   c.l = file_log_new ("log");
   c.k = keydis_vt102_new (&c);
 
-#if 0
-  terminal_register_handlers ();
-  a.terminal = terminal_open (0, 1);
-
-  ansi_reset (&a, NULL);
-#endif
 
   clients = clients_new ();
 
   for (;;)
     {
-      struct timeval tv = { 10, 0 };
+      struct timeval tv = { 1, 0 };
+
+      check_status (&c, clients);
 
       FD_ZERO (&rfds);
       FD_ZERO (&wfds);
 
       tty_pre_select (c.t, &rfds, &wfds);
-#if 0
-      tty_pre_select (a.terminal, &rfds, &wfds);
-#endif
 
       FD_SET (s->fd, &rfds);
 
@@ -145,23 +313,16 @@ main (int argc, char *argv[])
 
           if (red)
             {
-              clients_output (clients, buf, red);
+              send_output (clients, buf, red);
               vt102_parse (&c, buf, red);
             }
         }
 
-#if 0
-      ansi_dispatch (&a, &c);
-      ansi_update (&a, &c);
-#endif
 
 
     }
 
   clients_shutdown (clients);
-#if 0
-  ansi_terminal_reset (&a);
-#endif
   terminal_atexit ();
   printf ("QUAT\n");
 }