chiark / gitweb /
*** empty log message ***
authorjames <james>
Sat, 16 Feb 2008 10:58:52 +0000 (10:58 +0000)
committerjames <james>
Sat, 16 Feb 2008 10:58:52 +0000 (10:58 +0000)
apps/mainloop.c
apps/usage.c

index 5acee6fc6840f1e51affc3101671d8de4d9b837e..e3d2190420e2a95c94a8de9c4d87dee351954a91 100644 (file)
  *
  */
 
-static char rcsid[] = "$Id$";
+static char rcsid[] =
+  "$Id$";
 
 /*
  * $Log$
- * Revision 1.1  2008/02/16 01:30:56  james
+ * Revision 1.2  2008/02/16 10:58:52  james
+ * *** empty log message ***
+ *
+ * Revision 1.13  2008/02/15 23:52:12  james
+ * *** empty log message ***
+ *
+ * Revision 1.12  2008/02/15 03:32:07  james
+ * *** empty log message ***
+ *
+ * Revision 1.11  2008/02/14 16:21:17  james
+ * *** empty log message ***
+ *
+ * Revision 1.10  2008/02/14 10:39:14  james
+ * *** empty log message ***
+ *
+ * Revision 1.9  2008/02/14 10:34:47  james
+ * *** empty log message ***
+ *
+ * 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 ***
+ *
+ * Revision 1.4  2008/02/13 17:21:55  james
+ * *** empty log message ***
+ *
+ * Revision 1.3  2008/02/08 15:06:52  james
+ * *** empty log message ***
+ *
+ * Revision 1.2  2008/02/07 15:42:49  james
+ * *** empty log message ***
+ *
+ * Revision 1.1  2008/02/05 14:25:49  james
  * *** empty log message ***
  *
  */
 
+#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 blocked;
+  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;
+  status.blocked = tty_status.blocked;
+
+  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);
+
+  *(ptr++) = ' ';
+  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);
+
+  ptr += sprintf (ptr, "CTRL-B ");
+
+  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);
+  ptr = do_line (ptr, status.lines, TIOCM_CD);
+
+  if (status.blocked)
+    {
+      t = ", Locked";
+      while (*t)
+        *(ptr++) = *(t++);
+    }
+
+  if (status.crtscts)
+    {
+      t = ", Flow";
+      while (*t)
+        *(ptr++) = *(t++);
+    }
+
+#if 0
+  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);
+    }
+#endif
+
+  ptr +=
+    sprintf (ptr, ", %d client%s", status.nclients,
+             (status.nclients == 1) ? "" : "s");
+
+  *ptr = 0;
+
+  send_status (cs, buf);
+}
+
+
+  TTY *t;
+  Log *l;
+  t= ptty_open (NULL, NULL);
+  //t = serial_open ("/dev/cellmodem", 0);
+l=file_log_new ("log");
+
+
+void mainloop (TTY *tty,Socket *server_socket,Socket *client_socket,Ansi *a,Log *log)
+{
+  fd_set rfds, wfds;
+  Context c;
+  Clients *clients;
+
+  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) {
+       if (server_socket) abort();
+       c.s = client_socket;  
+        c.k = keydis_ipc_new (client_socket);
+  } else {
+       if (!tty) abort();
+       c.t = tty;
+       c.k = keydis_vt102_new ();
+  }
+
+  /* do we have an upstream terminal to talk to*/
+  if (ansi) {
+       c.d = cmd_new ();
+  } else {
+       c.d = NULL;
+  }
+
+
+  if (server_socket) {
+       if(client_socket) abort();
+       clients = clients_new ();
+  } else {
+       clients=NULL;
+  }
+
+  for (;;)
+    {
+      struct timeval tv = { 1, 0 };
+
+      check_status (&c, clients);
+
+      FD_ZERO (&rfds);
+      FD_ZERO (&wfds);
+
+       if (c.t)
+          tty_pre_select (c.t, &rfds, &wfds);
+
+       if (server_socket) {
+      FD_SET (server_socket->fd, &rfds);
+      clients_pre_select (clients, &rfds, &wfds);
+       }
+
+       if (client_socket)
+      socket_pre_select (client_socket, &rfds, &wfds);
+
+      select (FD_SETSIZE, &rfds, &wfds, NULL, &tv);
+
+      /*any message from clients, or new connexions*/
+      if (server_socket) {
+      Socket *cs;
+      if (FD_ISSET (server_socket->fd, &rfds) && ((cs = socket_accept (s))))
+        {
+          {
+            Client *cl;
+            /*New client connexion */
+            cl = clients_new_client (clients, cs, &c);
+
+            send_history (c.h, cl);
+            send_vt102 (c.v, cl);
+
+          }
+        }
+
+      clients_post_select (clients, &c, &rfds, &wfds);
+      }
+
+      /*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));
+
+          if (red < 0)
+            break;
+
+          if (red)
+            {
+              send_output (clients, buf, red);
+              vt102_parse (&c, buf, red);
+            }
+        }
+
+
+
+    }
+
+  clients_shutdown (clients);
+  terminal_atexit ();
+  printf ("QUAT\n");
+}
index 8bc00b9d4a909b2886dea3010c4694cd0090cd76..c0b81f376b052fd7a11d3a8f27761b35d7c188ce 100644 (file)
@@ -10,54 +10,58 @@ static char rcsid[] = "$Id$";
 
 /*
  * $Log$
+ * Revision 1.2  2008/02/16 10:58:52  james
+ * *** empty log message ***
+ *
  * Revision 1.1  2008/02/16 01:30:56  james
  * *** empty log message ***
  *
  */
 
 
-void usage(void)
+void
+usage (void)
 {
 
-fprintf(stderr, "Usage:\n"
-"sympathy -t      [-l] [-d serialdev|-p] [-b baud] [-h]\n"
-"sympathy -s      [-l] [-d serialdev|-p] [-b baud] [-h] [-f] [-k socket]\n"
-"sympathy [-s -c] [-l] [-d serialdev|-p] [-b baud] [-h] [-k socket]\n"
-"sympathy -c -k socket [-H]\n" 
-"sympathy -r id [-H]\n"
-"\n"
-"Main mode:\n"
-"   -t  terminal emulator mode: one process is started which reads from\n"
-"          the serial device or ptty and writes to the users terminal.\n"
-"   -s  server mode: a process is started (and daemonized unless -f is\n"
-"          given) which listens on a socket, and reads from the serial\n"
-"          device or ptty.\n"
-"   -c  client mode: connect to server mode process\n"
-"   -s -c  server and client mode. Fork a server and connect a client\n"
-"            incompatible with -f. This is the default mode\n"
-"   -r id  client mode: connect to server mode process on socket\n"
-"             ~/.sympathy/id\n"
-"\n"
-"Options:\n"
-"   -l  lock the serial device. By default sympathy checks that no\n"
-"          other process has create a lock file, and temporarily ceases\n"
-"          to access the serial port if it spots one. With this option\n"
-"          sympathy creates a lock file and prevents other programs\n"
-"          accessing the serial port. Incompatible with -p\n"
-"   -d serialdev  the serial device to connect to, eg /dev/ttyS0\n"
-"   -p   fork a login shell in a pty and connect to that rather than\n"
-"           connect to a serial port. This option is the default if\n"
-"           no -d option is specified\n"
-"   -b baud  the baudrate to set. If omitted sympathy does not set\n"
-"              a baudrate and uses the current setting\n"
-"   -h  set RTS/CTS flowcontrol. By default sympathy disables flow\n"
-"         control\n"
-"   -k socket  explicity set the name of the socket, by default\n"
-"                sympathy will use ~/.sympathy/$pid\n"
-"   -f  do not detach, run the server in the foreground\n"
-"   -H  instead of connecting the user's terminal to the session\n"
-"         emit HTML of the current state of the screen on stdout\n"
-);
+  fprintf (stderr, "Usage:\n"
+           "sympathy -t      [-l] [-d serialdev|-p] [-b baud] [-h] [-L log]\n"
+           "sympathy -s      [-l] [-d serialdev|-p] [-b baud] [-h] [-L log] [-f] [-k skt]\n"
+           "sympathy [-s -c] [-l] [-d serialdev|-p] [-b baud] [-h] [-L log] [-k skt]\n"
+           "sympathy -c      [-H] -k skt\n"
+           "sympathy -r id   [-H]\n"
+           "\n"
+           "Main mode:\n"
+           "   -t  terminal emulator mode: one process is started which reads from\n"
+           "          the serial device or ptty and writes to the users terminal.\n"
+           "   -s  server mode: a process is started (and daemonized unless -f is\n"
+           "          given) which listens on a socket, and reads from the serial\n"
+           "          device or ptty.\n"
+           "   -s -c  server and client mode. Fork a server and connect a client\n"
+           "            incompatible with -f. This is the default mode\n"
+           "   -c     client mode: connect to server mode process\n"
+           "   -r id  client mode: connect to server mode process on socket\n"
+           "             ~/.sympathy/id\n"
+           "\n"
+           "Options:\n"
+           "   -l  lock the serial device. By default sympathy checks that no\n"
+           "          other process has create a lock file, and temporarily ceases\n"
+           "          to access the serial port if it spots one. With this option\n"
+           "          sympathy creates a lock file and prevents other programs\n"
+           "          accessing the serial port. Incompatible with -p\n"
+           "   -d serialdev  the serial device to connect to, eg /dev/ttyS0\n"
+           "   -p   fork a login shell in a pty and connect to that rather than\n"
+           "           connect to a serial port. This option is the default if\n"
+           "           no -d option is specified\n"
+           "   -b baud  the baudrate to set. If omitted sympathy does not set\n"
+           "              a baudrate and uses the current setting\n"
+           "   -h  set RTS/CTS flowcontrol. By default sympathy disables flow\n"
+           "         control\n"
+           "   -k socket  explicity set the name of the socket, by default\n"
+           "                sympathy will use ~/.sympathy/$pid\n"
+           "   -f  do not detach, run the server in the foreground\n"
+           "   -H  instead of connecting the user's terminal to the session\n"
+           "         emit HTML of the current state of the screen on stdout\n"
+           "   -L  log activity on the device to the file log\n");
 
-exit(1);
+  exit (1);
 }